Drupal 7 FAQ
It is a CMS. An open source content and free CMS framework written in PHP. It enables you to organize, manage and publish content with variety of customizations.
Using "Content Construction Kit (CCK)" module drupal help build multiple content type without much of programming skills. And for each content type, it allows customized theme template.
Through caching, drupal allows to speed up website using different configurations such as Page Caching, Block Caching and Lifetime for cached pages.
- Page Caching :
It enables the entire HTML of each page to be stored in database. It reduces the amount of queries fired. Automatically, caches the blocks in pages.
- Block Caching :
Instead of complete page when partial section of page needs to be cached, block caching helps. Block created through view, one can set its caching default to "dont cache". "block_cache_alter" helps here.
- Min. Cache lifetime :
It's an amount of time before the page cache is cleared.
- Expiration of cached pages :
It only applies to external mechanism, e.g. browser cache or varnish etc.
- Modules for caching in Drupal :
- Alternative PHP Cache (APC)
- Varnish - Needs to have affected pages purged.
- MemCache - Basically works on DB Caching.
- Redis
- Boost
PDO mean PHP Data Object. It’s a lean and consistent way to access databases. Allows developer write a portable code at ease.
In database, drupal stores information and each info. has its own database table. E.g. basic node entries are stored in a node table & if cck is used, each field value is stored in a separate table.
Drush is command line shell intergace for Drupal to manage drupal fast and easy. This scripting shell needs to be installed separately on server. And one needs to have SSH(secured shell) access in order to use drush.
Click Here for more drush commands.
Modules are like plugin for your site. It allows you to add different functions to the site. Some of modules are - a. panels b. rules c. quicktabs d. views e. tokens f. ctools g. pathauto etc.
- pathauto
- metatags
- google analytics
- sitemap
- url lists
Drupal weight term is used to define the priority or order in which function will be processed. A heavier (+10) will appear lower in list while lighter (-10) will float to the top of list.
MySQL, Maria DB, Mongo DB, PostgresSQL, SQLlite etc
This suit is set of APIs and tools. It makes easier to handle AJAX requests.
"db_drop_table" in install file will do the trick.
"URL Settings" & "pathauto" are the modules that help SEO friendly URLs for the site.
"Taxonomy Terms" are most powerful keyword hierarchy which provides category based organized information.
hooks are drupal code, basically functions, that helps developers to interact with core & extend drupal system and in turn site functionality. Each hook has a defined set of parameters and specified result type.
e.g. hook_menu, hook_form_alter, hook_form_id_alter etc.
It allows the use of diff. database server using the same code. An abstraction layer helps here with ability to support multiple db servers.
Using devel module in Drupal, one can use dsm & dpm functions to debug the code. In else case, simply using print_r or var_dump one can debug in Drupal.
A node in drupal is generic term used for a piece of content on your website. Stored in table called "node". Each node has a content type. It also has, node id, a title, description, user id, creation date etc.
The content construction kit (cck) module allows developers to add custom fields to custom content types. In Drupal 7 and later, most of cck is absorbed in core. Using cck, developers can create a content types & can have exactly the fields needed.
"pathauto" module helps generating URL Aliases automatically for new content.
One can access login screen in such cases by simply typing URL: http://sitename.com/?q=user OR http://sitename.com/user if clean url is enabled.
Similarly, one can logout using http://sitename.com/q=logout OR http://sitename.com/logout if clean url is enabled.
Go to the phpMyAdmin & access the drupal db. Now, fire a query to update the password for a user with uid as 1.
At location, Admin -> site building -> themes click configure link next to current theme. In theme configuration page, you will find a section titled shortcut icons settings. Upload favicon in here.
In D7, new concept of "entity" is introduced which makes it framework. User reference and node reference is replaced with entity reference. cck module is moved into core. Also, system requirements has been reduced and security is enhanced. AJAX is introduced in D7 to replace AHAH (Asynchronous HTTP and HTML). Coding section uses PDO (PHP Data Object) so as to interact different types of databases.
In earlier version, the field system was used only on the content types. Now, with the help of entity API, we can add fields to other things such as comments, user profiles etc. An entity type is useful abstraction to group together fields. Nodes (Content), comments, user profiles are example of entity types.
Bundles are implementation of entity type to which fields can be attached. Bundles are subtypes of entity type. With content node(entity type) one can generate bundles(subtype) like articles, blog posts etc., Using field system, you can add different fields to each bundles.
Fields is primitive data type, with custom validators and widgets for editing & formatters for display.
An entity would be one instance of particular entity type such as comment, taxonomy or user profile.
In terms of OOPs concept -
- An entity type is base class
- A bundle is an extended class
- A field is a class member, property, variable
- An entity is an object of base class OR extended class.
We can probably use nodes for nearly everything but when it comes to performance sensitive projects, codes should be used for content & we should separate as much as possible from codes. Because, nodes are revisioned, they fire lots of hooks & they have functionality that we likely don't need.
For demo purpose, we would define our own custom entity type named "project" & custom module called "demo".
-
First, we would define our own entity type. We need to declare its schema definition. This would go in demo . install file In this file implement the hook called hook_schema().
function demo_schema(){
$schema = array();
$schema['demo_projects'] = array(
'description' => ' the base table for project entity',
'fields' => array('id' => array('description' => 'primary key',
'type' => 'serial',
'not null' => TRUE),
'name' => ' ... ');
);
}This simple implementation of 'hook_schema' through which we create a 'demo_projects' table.
-
Now, next thing is to implement hook_entity_info. This hook goes in info . module file.
With this hook, we return a new key in associative array that represents entity machine name. With this, we have registered our own basic entity type.
-
Finally, register a path with Drupal using hook_menu and write below lines in callback function.
$projects = entity_load('project', array(1, 2));
dpm($projects);Here, we use entity_load function to load entities.
-
You can also save a new entity in code as :
$entity = entity_create('project', array(id => 3));
$entity->name = t('spring house');
$entity->save();
The main role of preprocessor is to setup variable to be placed within the template ( .tpl.php ) files. In D7, they apply to templates and functions.
In template . php file of theme folder.
You can set regions in themename.info file
e.g. regions[header] = Header
regions[footer] = Footer etc.
Use PHP APC, memcache(works on database level), varnish(needs pages cache to be purged), boost module and views cache_block cache.
For very high traffic, use the CDN module.
For Drupal 6 - MyISAM & for Drupal 7 - InnoDB
with hook_update_N()
with function db_drop_table in . install file.
strstr - finds the position of first occurrence of substring
substr - actually returns the substring from given string.
Yes, it will work. It will check for node . tpl . php file.
Yes, with function db_query() one can write query.
e.g. result = db_query("select * from node where nid = :nid", array(':nid' => $nid));
Using 'captcha' & 'recaptcha' module.
Using drush
Use 'profile' module. In D7 its in core.
You can also add fields through . install file
In form_alter hook use '#required' => TRUE
Singleton design pattern is used in Drupal.
The features module enables the capture and management of features in Drupal. A feature is a collection of Drupal Entities which taken together satisfies a creation use case.
Features provide a UI & API to take different site building component and bundling them in a single feature module.
Panels module allows a site administrators to create customized layouts for multiple uses. You can panelize virtually any page with site including index page.
This suit is primarily a set of API & tools to improve the developer experience. It also contains a module called 'page manager' whose job is to manage page. In particular, it manages panel pages but as it grows, it will be able to manage far more than just panels.
- hook_menu()
It has
'page callback' - name of function to execute upon clicking link.
'page argument' - array of arguments to pass to callback
'delivery callback' - name of function to package and return the results received from 'page callback'.
'access callback' - name of function to check permission to check access rights, defaults to user_access().
'access arguments' - array of arguments to pass to 'access callback' if default user_access() is to be called then this parameter is mandatory. - hook_form_alter($form, &$form_state, $form_id)
- hook_form_FORM_ID_alter(&$form, &$form_state, $form_id)
$form['#attached']['css'] = array(drupal_get_path('module', 'ajax.css'))
$form['#attached']['js'] = array(drupal_get_path('module', 'ajax.js'))
module_invoke_all($hook) takes hook name as parameter and invokes that particular hook in all enabled modules.
module_invoke($module, $hook) invokes a particular hook of particular module passed in parameters.
hook_boot performs setup tasks on all pages including cached pages. Its called before modules when Drupal is still in bootstrap mode.
hook_init performs setup tasks on only non-cached pages. Call to this hook happens after bootstrap which means all modules are loaded while call to this hook.
Doesn’t make any difference. Site continues running as it was.
Stops site working with Error 404. I suppose, rewrite conditions along with other settings does fail for the site.
You can enable caching of individual views at right side under section 'Other' on view configuration page. You get two options viz., 'None' & 'Time-based'. Caching mechanism for this screen also can be adjusted in settings page. Upon selection of 'Time-based', you can either set query result i.e. 'Raw Query Result' or 'Rendered HTML Output' altogether for caching. DB table cache_views stores the blob type data for this caching. This is actually serialized data stored.
'cache_set', 'cache_get' & 'cache_clear_all' are couple of functions in caching, that can be used for handling caching manually through code.
'variable_set' & 'variable_get' are functions used in Drupal 7. However, there functions are deprecated in Drupal 8 and are replaced with config()->set & config()->get functions.
bootstrap . inc is the file containing all the functions that needs to be loaded on every Drupal request.
- arg - function that returns a component of the current path.
- drupal_load - includes a file with provided type and name of file.
- t - function that translates a given string to current language or to the given language.
- variable_del - unsets persistent variable.
- variable_get - returns persistent variable.
- variable_set - sets a persistent variable.
This file also contains default constants needed in drupal. For instance, VERSION, REQUEST_TIME etc.,
Bootstrap is basically CPU of drupal. Drupal's core waits for a path request & then start processing that request with bootstrap.
We would need to create a custom module. Inside . install file of this module we need to call a hook named hook_enable in which we would need to create an associative array of fields with field name, type etc.,
Then pass this returned array to function field_create_field.
We need to ensure to bind these fields to an entity bundle with function field_create_instance which will have $instance as parameter which would be actually an associative array with field name created above, node and bundle for that field to bind.
To Remove the field above process goes in reverse way i.e. in hook_disable hook give calls to field_delete_instance & then field_delete_field.
- hook_process_page - Overrides or inserts variables into the page template.
- hook_process_html - Overrides or inserts variables into the page template or HTML output.
- hook_preprocess_html - Add body classes if certain regions have content.
- hook_preprocess_node - Overrides or inserts variables into node template.
- hook_preprocess_block - Overrides or inserts variables into block template.
The . info file is a static text file for defining and configuring the theme.
Each line in . info file is key-value pair with the key on left and value on right side.
name & core are the two entries that are mandatory.
Responsive design is an approach to web design aimed at crafting sites to provide optimal viewing experience. Easy reading & navigation with minimum resizing, panning & scrolling across wide range of devices.
Responsive design adopts the layout by using fluid, proportion based grid, flexible images & CSS media queries (@media ). CSS framework & table less design helps achieve RWD.
7 Steps to build Responsive theme :
- Understand your design & decide on breakpoint.
- Start with theme info file. Include CSS files in it.
e.g.
stylesheets[all][] = css/reset.css
stylesheets[all][] = css/main.css
stylesheets[(min-width: 480px)][] = css/480.css
stylesheets[(min-width: 768px)][] = css/768.css
stylesheets[(min-width: 1024px)][] = css/1024.css
stylesheets[(min-width: 1280px)][] = css/1280.css - Create HTML5 pages for each unique page in website.
- Segregate styles for different breakpoints using media queries.
e.g.
stylesheets[all and (min-width: 600px)][] = css/600.css OR write inline media queries in CSS file. - Embed device specific meta tags in html . php . tpl file
- For IE Support, add respond.js & selectivizr.js files to the theme.
- Finally, test theme in default drupal installation.
Voila, here we have Drupal 7 Theme that is responsive.
There are 7 different ways to do so :
- drupal_add_js() function and drupal_add_css() function for css.
In drupal_add_js() function, you can pass second parameter as associative array, to avoid inclusion on all page as :
drupal_add_js(file_path, array('every_page' => FALSE));
- including it in . info file.
- ['#attached'] - best for forms and doesn't get included on all pages.
- drupal_add_library() function
- hook_js_alter(&$js) and hook_css_alter(&$css) for css.
- drupal_add_html_head() function.
- including as html in . tpl . php page. - Don't do this way.
There are two ways to do so :
- Drupal GUI : Structure -> Blocks -> Add Block.
This approach could be used when no customization or PHP code required.
- Through custom module -
- hook_block_configure - to define configuration for block
- hook_block_info - to define all blocks for module.
- hook_block_save - to save the defined block.
- hook_block_info_alter - to change block definitions on the fly.
- hook_block_view - to return block for rendering.
Yes, its possible. With the help of "Sections" module it can be achieved easily.
- Create a node
- Remember node id
- Go to Admin -> Site Configuration -> Error Reporting
- Set Default 404 Page to node id just created
- Save Settings.
While reviewing the code I was looking for optimizing the site for better performance.
There are various levels of optimizations :
- Code Optimizations : Try & see if there are possible ways of optimizing code e.g. replace switch statement for multiple if OR use n * (n+1) / 2 formula to add numbers rather than loop.
- DB Optimization : Optimize query & SQL Statements optimizing with indexes, check for locking & caching etc.,
- Design Level Optimizations : Break down larger images into multiple smaller smaller ones. It loads faster. Use fluid DIV structure instead of table, td structure.
Drupal has a system for classifying content known as Taxonomy. This is provided by core module. You can define your own vocabulary or groups of taxonomy terms and add terms to each vocabulary. Each vocabulary can then be attached to one or more content type. And in this way, nodes on your site can be grouped into categories.
To write a cron you need to implement hook_cron() in your module. Then, drupal will automatically execute these tasks during the default cron handling.
Note that, using drupal_set_message() function in a hook_cron() implementation makes no sense because there is no user to read these messages. As an alternative, you could log messages with watchdog().
To execute commands or scripts automatically at specified time and date intervals, drupal cron is used.
In Drupal 7 you can enable cron via the Administration > Configuration > System > Cron (admin/config/system/cron)
In Drupal 8 you can enable cron via Menu > Configuration > System > Cron (admin/config/system/cron).
The default frequency is every three hours. Cron will then be triggered by end users visiting your site, no more frequently than every three hours.
Note that, for low-traffic sites it can also be desirable to create a cron job(More Info @ https://drupal.org/cron & https://drupal.org/node/23714).
Make a note, 'elysia_cron' is the module which is generally good and used to manage the crons for drupal setup..
Basic default crons by drupal 7 are:
dblog_cron (w) Remove expired log messages and flood control events [runs every hour]
field_cron (w) Purges some deleted Field API data, if any exists [runs every hour]
node_cron (w) History table cleanup [runs every hour]
search_cron (w) Update search database index [runs every hour]
system_cron (w) Remove older rows from flood and batch table. Remove old temporary files. [runs every hour]
update_cron (w) Checks for available updates of Drupal core, contributed modules and themes [runs every hour]
$GLOBALS is the variable one should use to alter the global variables in drupal site.
e.g. $GLOBALS['conf']['language)default'] will change the global language variable for entire site.
Must make a note, just defining global $language and then setting value to $language does not alter the global value of variable but only for that function or page... once moved to next page or function, this new assigned value is lost for $language global variable...so this is not ideal way... Instead use, $GLOBALS variable...
Drupal has a global $user object, which represents the currently-logged-in user. which can be accessed as
global $user;
print_r($user->uid);
print_r($user->name);
user_load($user->uid) : function call to load all the information about user currently logged in
Thus,
global $user;
$arrCurrUser=user_load($user->uid);
$arrCurrUser->field_gender['und'][0]['value']; => To get Gender of user
So to avoid confusion and to avoid clobbering the global $user object, it is a good idea to assign the result of this function to a different local variable, generally $account.
user_load_multiple Function Loads multiple users based on certain conditions. This function should be used whenever you need to load more than one user from the database. Users are loaded into memory and will not require database access if loaded again during the same page request.
Make a note, there is no global $node variable available for Drupal, since no global entity of type node can be set as every page(atleast most of pages) runs as nodes in Drupal, so it wont be possible to set any specific node as global like user... However, to retrieve the node details of current page, one can use..
if (arg(0) == 'node') {
$nid=arg(1);
isset($nid)&&is_numeric($nid)?$nid=arg(1):$nid=arg(3);
if ($nid) {
$currNode = node_load($nid);
}
}
if($currNode->type!='group'){
// Do whatever action needed
}
array_unshift($form['#validate'], 'name of function');
$form['email']['#access'] = FALSE;
hook_node_presave hook acts on a node being inserted or updated.
$query = db_select('node', 'n');
$query->innerjoin('users', 'u', 'n.uid=u.uid');
$query->fields('n', array('nid', 'name'));
$query->execute();
$query = db_select('role', 'r');
$query->addTag('translatable');
$query->fields('r', array('rid', 'name'));
$query->orderBy('weight');
$query->orderBy('name');
if (!empty($permission)) {
$query->innerJoin('role_permission', 'p', 'r.rid = p.rid');
$query->condition('p.permission', $permission);
}
$result = $query->execute();
$query = db_select('node', 'n');
$query->join('users', 'u', 'n.uid = u.uid'); //JOIN node with users
$query->groupBy('u.uid');//GROUP BY user ID
$query->fields('n',array('title','created'))//SELECT the fields from node
->fields('u',array('name'))//SELECT the fields from user
->orderBy('created', 'DESC')//ORDER BY created
->range(0,2);//LIMIT to 2 records
$result = $query->execute();
while(
$record = $result->fetchAssoc()) {
print_r($record);
}
$query = db_select('role', 'r');
$query->addTag('translatable');
$query->fields('r', array('rid', 'name'));
$query->orderBy('weight');
$query->orderBy('name');
if (!empty($permission)) {
$query->innerJoin('role_permission', 'p', 'r.rid = p.rid');
$query->condition('p.permission', $permission);
}
$result = $query->execute();
// Add a cancel button.
$form['actions']['cancel'] = array(
'#type' => 'button',
'#value' => t('Cancel'),
'#weight' => 51,
'#ajax' => array(
'effect' => 'fade',
'callback' => 'custom_blaahh_node_form_cancel',
),
'#limit_validation_errors' => array(),
);
function custom_blaahh_node_form_cancel($form, &$form_state){
$commands[] = ajax_command_invoke('.node-blaa-form', 'remove'); // Remove existing form first if available..
return array('#type' => 'ajax', '#commands' => $commands);
}
$newPath = $base_url.'/'.str_replace('add/xyz/', 'abc/',current_path());
ctools_include('ajax');
ctools_add_js('ajax-responder');
$commands[] = ctools_ajax_command_redirect($newPath);
print ajax_render($commands);
drupal_exit();
var strHttp = location.protocol;
var strSlashes = strHttp.concat("//");
var strHost = strSlashes.concat(window.location.hostname);
var strAutocompleteUsersPageURL = strHost.concat("/autocomplete-users?combine=");
RESTful webservices are best to use.
Advantages of REST webservices are :
- Light weight, not a lot of extra xml markup.
- Human readable results.
- Easy to build, no toolkit required.
SOAP also has few of its advantages :
- Sometimes, easy to consume.
- Rigid type checking, adhere to contracts
- Development tool.
* It is easy to create SOAP webservices, but are difficult to consume them.
* RESTful webservices are difficult / hard to create but are easy to consume them.
* SOAP is heavy weight, while REST is light and mobile friendly.
Conclusion : SOAP is not necessarily bad. It's just that REST is better.
JSON is much better than XML.
- JSON is simpler than XML.
- XML is markup language that needs to define tags & attributes which makes XML rich but heavy. Whereas, JSON, does not need such tags and directly maps onto data structure & hence is light weight.
- On account of readability, extensibility, openness and simplicity both JSON & XML match.
All in all, JSON is better & mostly suggested.
Add new comment