Wednesday, January 9, 2008

Is Drupal Easy?

Yes, Drupal is easy if you understand the architecture of the system. If you don't understand it then it is the most unwanted thing for you. I am listing down certain points which I had noticed while exploring Drupal.

  1. Most of the things can be managed through administer screen. It is just a matter of exploring all the available options. Some of the important features you need to be aware are categories, content types, Blocks, Menu, themes, Modules, Access control, Roles and module wise configuration.
  2. Access control is a very important feature where in you can define the permissions, which user can see what specific pages. You can also create your own access permissions for your custom modules. I will talk about custom modules little later.
  3. If you know that there are different roles in your website, I would suggest you to create roles and access permissions based on it.
  4. When you install Drupal, by default you will have 3 content types (Blog, Story and Page). You can also create your own custom content type by choosing content types option under content management in administer screen.
  5. When you install Drupal, there are some basic modules will be available. Drupal is being used by many users and everyday there are lot of modules being contributed. Visit http://drupal.org/project/Modules for a list of modules that are available in Drupal.

    If you want to use any specific module, download the tar file, untar it and copy it into the modules directory of your Drupal installation. Go to Administer screen->site building->Modules. You will see your module in the list with a Checkbox. Select the module and save it. Now your module should appear in the navigation bar. Do not forget to give permissions on the module to users using access control. Otherwise, normal users will not have access to new modules.

  6. Themes are very simple and powerful feature of Drupal. Themes are none other than different layouts for your website. There are plenty of themes available such as 2-column, 3-column, fixed width, etc. If you had created your own theme or downloaded, copy it into themes directory. Go to administer screen->themes and you will see your new theme visible. Enable and select as default to apply the theme.
  7. Clean urls are used basically to help Google in indexing our pages and also to have the urls look clean. This can be done by enabling rewrite module in httpd.conf file of apache and then enable clean-urls from administer screen.
  8. Basically the content in Drupal is referred to as node. Whatever content we create using create content is referred to as node.

    Workflow
  9. All the code will be written in modules. In every module directory, you will have .module file which contains all the business logic. Everything will be in the form of functions. To understand the flow, always check for _menu() function. It basically contains the items[] array, which contains the list of main functionalities that can be accessed through links or from URL. All other functions will be called from these functions. Here is basic example of chatroom.module menu

    function chatroom_menu($may_cache) {
    $items = array();
    $items[] = array(
    'path' => 'admin/settings/chatroom',
    'callback' => 'drupal_get_form',
    'callback arguments' => array('chatroom_admin_settings'),
    'title' => t('Chat room'),
    'description' => t('Configure chat rooms.'),
    'access' => user_access('administer chat rooms')
    );
    $items[] = array(
    'path' => 'chatrooms',
    'callback' => 'chatroom_page',
    'access' => user_access('access chat rooms'),
    'title' => t('Chat rooms'),
    'type' => MENU_SUGGESTED_ITEM
    );
    $items[] = array(
    'path' => 'chatrooms/kicked',
    'callback' => 'chatroom_chat_kicked_user',
    'access' => user_access('access chat rooms'),
    'type' => MENU_CALLBACK
    );
    return $items;
    }

    Now there are 3 elements declared in items[]. The path in the items[] is basically the one used in the URL. Whenever that particular path is accessed, the callback function will be called with arguments (if present). Title and description are explanatory to the menu items. Through access, you can restrict the permissions of the user. There are 3 types of menu values that can be given in items[]. MENU_NORMAL_ITEM, MENU_CALLBACK, MENU_SUGGESTED_ITEM.

    MENU_NORMAL_ITEM: Normal menu items show up in the menu tree and can be moved/hidden by the administrator. This will be used for most menu items. It is the default value if no menu item type is specified.
    MENU_CALLBACK: Callbacks simply register a path so that the correct function is fired when the URL is accessed. They are not shown in the menu. This will be used when you want some function to be called when someone access the particular URL but does not want to show it anywhere. Then you can use MENU_CALLBACK.
    MENU_SUGGESTED_ITEM: They act just as callbacks do until enabled, at which time they act like normal items. Administrator will have option either to enable/disable the item from menu.

    So whenever you want to know the flow of any particular module, check for module_menu() function and then check the items array. If you want to add also, just modify the items[]. Please note that anytime you change anything in items[], you need to disable and then enable again to get the modified one working.

  10. To create your own custom module, copy any module file and modify the changes to module_menu(). Remove unnecessary functions. There are 3 main things that you have to be aware of while creating our own module.

    mymodule_help() will basically contains any help material for that particular module. Whenever you go to administer screen and click administer by module, for each module, you see some help text. This help text will be generated in this section only. So while creating, add your own text to mymodule_help().

    mymodule_perm() is another important function which will help you to determine the access permissions that this particular module will have. If you go to Administer->user management->access control, for each module, you will see different permissions. To define permissions for your module, you need to write it in this function only.

    function mymodule_perm() {

    return array('access chatroom', 'edit own chatroom', 'administer room');

    }

    This will create 3 permissions for our module and will be displayed in access control page under your module.

    Now write mymodule_menu() which defines the items[] as explained above.
  11. If we are creating our own module, it means that basically we are going to create forms, validations, submissions, database queries, etc. Drupal provides a flexibility of creating custom forms very easily. Here is basic form in Drupal to be used

    function mymodule_form($id)
    $form['mymodule_form']['name'] = array(
    '#type' => 'textfield',
    '#title' => t('Name'),
    '#required' => TRUE
    );
    $form['mymodule_form']['description'] = array(
    '#type' => 'textarea',
    '#title' => t('Description'),
    '#rows' => 3,
    '#description' => t('Describe'),
    );
    $form['mymodule_form']['id'] = array(
    '#type' => 'hidden',
    '#value' => $id
    );
    $form['mymodule_form']['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Okay')
    );

    return $form;
    }

    The above creates a simple form which contains one text field, text area and a submit button. When we create a form, we need to validate it and also have to write code in submit block. To validate a form, you need to write a function which has same name as form function appended with "validate". Here is a example

    function mymodule_form_validate($f_id, $f_values) {
    $rid = $f_values['id'];
    $name = $f_values['name'];
    if ($name =="admin") {
    form_set_error('mymodule_form', t('A name called %name already exists.', array('%name' => $name)));
    }
    }

    Whenever you submit a form, a validate function will be called. $f_values will basically contains all your form values and $f_id will be your form id. So using $f_values['name'] will give you the value input by the user in name field.

    Here is the sample function for onsubmit.

    function mymodule_form_submit($f_id, $f_values) {
    global $user;

    $created = db_query("
    INSERT INTO {mytable} (id, name, description)
    VALUES (%d, '%s', '%s'')
    ", $f_values['id'], $f_values['name'], $f_values['description']);
    if (!$created) {
    drupal_set_message(t("There was an error creating your room"), 'error');
    }
    drupal_goto('mypath');
    }

    There are different ways of executing sql queries. I will discuss some of them here. Before discussing that, let me tell you about drupal_goto. It is similar to redirection in any other language. After the form is submitted, you want the form to be redirected to home age. Drupal_goto will do the same.

    You can have sql query being stored in the string and using db_query($sql) can execute the query and store it in $result variable. For example,

    $sql = "SELECT name FROM {mytable} WHERE name = '%s' ";
    $result = db_query($sql,$name);

    $name will be substituted in the query above in place of %s. Once the query is executed, it is store in $result variable. We can check whether the query returned any values or not by checking

    if (db_num_rows($result) > 0) {

    }

    Once it is true, then you can write within if condition to get the values. such as

    if (db_num_rows($result) > 0) {
    while($user_det = db_fetch_object($result)) {
    //values can be accessed like this.
    $name = $user_det->name;
    $desc = $user_det->description;
    }
    }

    Now you understand the creation of form, validation, submission, control structures and handling database queries. The main thing you need to understand is about rendering the form which you had created earlier. Everything here is functions. So this function has to be called somewhere and also to be rendered in as an HTML form.

    function mymodule_create() {
    $output = '';
    $sql = '
    SELECT max(id) as id from {mytable}
    ';
    $result = db_query($sql);
    if (db_num_rows($result) > 0) {
    $ud = db_fetch_object($result);
    $id = $ud->id + 1;
    } else {
    $id = 1;
    }
    //the below if condition checks whether the logged in user has access permissions 'administer mymodule' or not. If you uncheck the permission access for logged in user from access control, then the below if condition will be false.
    if (user_access('administer mymodule')) {
    $output .= drupal_get_form('mymodule_form', $id);
    }
    return $output;
    }

    Everything that gets dispalyed on the page will be stored in $output variable. The function drupal_get_form will basically takes the form name and the argument as id. so basically the above code has to be declared in items[] with the path as "mymodule/create". So whenever a user accesses the link, the form gets rendered and displayed.
  12. With the above knowledge, you can play around with Drupal. There are some other small things that can be useful such as sending mail, adding JavaScript and css.
  13. To send mail, there is a function drupal_mail('mymodule', $to, "subject", "Body",$from) ;
  14. To add javascript to your module, drupal_add_js((drupal_get_path('module', 'mymodule') .'/myjavascript.js');
  15. To add css to your module, drupal_add_css(drupal_get_path('module', 'mymodule') .'/myfolder/style.css', 'module', 'all', FALSE);