Drupal Code: Day 1
where am i, and how did i get all these arrays
Hi. I’m eaton.
Drupal is...




http://www.flickr.com/photos/druclimb/282597447/
Drupal is...




                                      Drupal Core



http://www.flickr.com/photos/druclimb/282597447/
Drupal is...



                                                       Node
                                      Drupal C...
Drupal is...

                          Views                   Five Star   CCK


                                        ...
Drupal is...
                                                  Theme


                          Views                   F...
Drupal is...
                                                  Theme


                          Views                   F...
name = Demo
description = Just a simple demo module.
core = 6.x

function demo_nodeapi(&$node, $op) {
  global $user;
  if...
name = Tricky
description = A slightly trickier module.
core = 6.x

function tricky_form_alter(&form, $form_state, $id) {
...
views.info   views.module      views.inc         user.inc         node.inc       blog.inc




comment.inc      ui.info    ...
views.info   views.module      views.inc         user.inc         node.inc       blog.inc




comment.inc      ui.info    ...
views.info   views.module      views.inc         user.inc         node.inc       blog.inc




comment.inc      ui.info    ...
under
                                                  the hood
http://www.flickr.com/photos/sprakope/143770402/
I’d like welcome.html!
I’d like welcome.html!
I’ll go get that html file!
I’ll go get that html file!
I’ll go get that html file!
      .htaccess says to check…
         index.php?q=welcome.html
Index.php? I’ve got that.
Index.php? I’ve got that.


          bootstrap.inc menu.inc   random




             mysql       user
Here are all my URLs…
function mymodule_menu() {
     $items['about'] = array(
      'title' => 'About us',
      'description' => 'A descriptio...
function mymodule_menu() {
     $items['about'] = array(
      'title' => 'About us',
      'description' => 'A descriptio...
What’s the best match?
What’s the best match?
      Is welcome.html an alias?
        Does anyone handle the path?
          Does the user have a...
I’ll build the contents.
function mymodule_about($subpage = ‘legal’) {
     if ($subpage == ‘legal’) {
       return “We don’t have lawyers yet.”;
...
function mymodule_about($subpage = ‘legal’) {
     if ($subpage == ‘legal’) {
       return “We don’t have lawyers yet.”;
...
I’ll take that HTML...
I’ll take that HTML...
I’ll take that HTML...
I’ll take that HTML...
Here’s index.php…
     Eh, looks like welcome.html…
don’t                            use a
                 hack.                            hook!


http://www.flickr.com/phot...
A list of content types
 A user is           is being built
registering
      A node is being   Content is being
         ...
module_invoke_all(‘foo’)
yourmodule_foo()
theirmodule_foo()
         mymodule_foo()
    yourmodule_foo()
hismodule_foo()
       hermodule_foo()
function demo_nodeapi(&$node, $op) {
  global $user;
  if ($op == ‘view’ && $node->uid == $user->uid) {
    $node->title ....
i
i

    ?
i

    ?
i

    ?
i
    All w i t h o u t
  h a ng ing Dr u p a l’s
c
      o w n c o de !
                     ?
Don’t. Hack. Core.
Don’t. Hack. Core.
let’s see
                                                    a module!
http://www.flickr.com/photos/gonzales2010/8632116/
name = Birthday
description = Wishes users a happy birthday.
requirements[] = user
core = 6.x
name = Birthday
description = Wishes users a happy birthday.
requirements[] = user
core = 6.x
/**
 * Allows users to save their birthday,
 * and congratulates them on the big day.
 */

function birthday_menu() {
  $i...
/**
 * Allows users to save their birthday,
 * and congratulates them on the big day.
 */

function birthday_menu() {
  $i...
function birthday_form() {
  $form['birthday_age'] = array(
   '#type' => 'checkbox',
   '#title' => t(quot;Show users how...
function birthday_form() {
  $form['birthday_age'] = array(
   '#type' => 'checkbox',
   '#title' => t(quot;Show users how...
function birthday_user($op, &$edit, &$account) {
  if ($op == 'view' && $day = $account->birthday) {
    $timestamp = mkti...
function birthday_user($op, &$edit, &$account) {
  if ($op == 'view' && $day = $account->birthday) {
    $timestamp = mkti...
function birthday_user($op, &$edit, &$account) {
  if ($op == 'view' && $day = $account->birthday) {
    $timestamp = mkti...
function birthday_block($op = 'list') {
 global $user;
   if ($op == 'list') {
   $block['congrats']['info'] = t('Birthday...
function birthday_block($op = 'list') {
 global $user;
   if ($op == 'list') {
   $block['congrats']['info'] = t('Birthday...
function birthday_block($op = 'list') {
 global $user;
   if ($op == 'list') {
   $block['congrats']['info'] = t('Birthday...
function birthday_song() {
 $path = drupal_get_path('module', 'birthday');
 $path .= '/birthday.mid ';
 $output = '<embed ...
function birthday_song() {
 $path = drupal_get_path('module', 'birthday');
 $path .= '/birthday.mid ';
 $output = '<embed ...
http://www.flickr.com/photos/thomashawk/2681744739
drupal manages the page




                      http://www.flickr.com/photos/thomashawk/2681744739
drupal manages the page
        modules build the content




                       http://www.flickr.com/photos/thomashaw...
drupal manages the page
            modules build the content
modules also respond to events




                         ...
drupal manages the page
            modules build the content
modules also respond to events
              hack with hooks...
api.drupal.org
   tinyurl.com/drupal-code
tinyurl.com/drupal-kickstart
 tinyurl.com/drupal-rocking
Drupal Development
Drupal Development
Drupal Development
Upcoming SlideShare
Loading in...5
×

Drupal Development

8,923

Published on

Intro to Drupal Development (Part 1), originally presented at the Chicago CMS Expo. See http://cmsexpo.net for details and other session information.

Published in: Technology, Design
1 Comment
26 Likes
Statistics
Notes
  • amazing ...
    where can i findout the Drupal Code: Day 2...??
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total Views
8,923
On Slideshare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
373
Comments
1
Likes
26
Embeds 0
No embeds

No notes for slide






  • Core - bootstrap, route incoming page requests to modules
    Modules - Build page content and respond to events
    Many third-party modules, some build on top of other modules
    Theme - Turn data from modules into HTML.



    We&#x2019;ll be concentrating on the module side of things today.
  • Core - bootstrap, route incoming page requests to modules
    Modules - Build page content and respond to events
    Many third-party modules, some build on top of other modules
    Theme - Turn data from modules into HTML.



    We&#x2019;ll be concentrating on the module side of things today.
  • Core - bootstrap, route incoming page requests to modules
    Modules - Build page content and respond to events
    Many third-party modules, some build on top of other modules
    Theme - Turn data from modules into HTML.



    We&#x2019;ll be concentrating on the module side of things today.
  • Core - bootstrap, route incoming page requests to modules
    Modules - Build page content and respond to events
    Many third-party modules, some build on top of other modules
    Theme - Turn data from modules into HTML.



    We&#x2019;ll be concentrating on the module side of things today.
  • Core - bootstrap, route incoming page requests to modules
    Modules - Build page content and respond to events
    Many third-party modules, some build on top of other modules
    Theme - Turn data from modules into HTML.



    We&#x2019;ll be concentrating on the module side of things today.
  • Core - bootstrap, route incoming page requests to modules
    Modules - Build page content and respond to events
    Many third-party modules, some build on top of other modules
    Theme - Turn data from modules into HTML.



    We&#x2019;ll be concentrating on the module side of things today.
  • Core - bootstrap, route incoming page requests to modules
    Modules - Build page content and respond to events
    Many third-party modules, some build on top of other modules
    Theme - Turn data from modules into HTML.



    We&#x2019;ll be concentrating on the module side of things today.
  • Core - bootstrap, route incoming page requests to modules
    Modules - Build page content and respond to events
    Many third-party modules, some build on top of other modules
    Theme - Turn data from modules into HTML.



    We&#x2019;ll be concentrating on the module side of things today.
  • Core - bootstrap, route incoming page requests to modules
    Modules - Build page content and respond to events
    Many third-party modules, some build on top of other modules
    Theme - Turn data from modules into HTML.



    We&#x2019;ll be concentrating on the module side of things today.
  • This is a module. Two files, A few lines of code.
    In Drupal, that&#x2019;s all you need to customize the behavior of the system and add new functionality.
  • A little more complicated. Shorter function, has an .install file.


  • This is a module, too. Views, one of Drupal&#x2019;s most popular, contains over 400 files, over a meg of code and inline docs.
    Don&#x2019;t worry, there&#x2019;s a middle ground.
    We&#x2019;re going to cover what they have in common.
  • This is a module, too. Views, one of Drupal&#x2019;s most popular, contains over 400 files, over a meg of code and inline docs.
    Don&#x2019;t worry, there&#x2019;s a middle ground.
    We&#x2019;re going to cover what they have in common.


  • Part 1: user with a web browser makes a request.
    sends a URL, optionally a cookie.



    http://www.mysite.com/articles/welcome.html


  • Apache intercepts the request.
    Possibly routes it to other servers
    What folder should I look in for foo.com?
    Normally, it would then check /articles for a welcome.html file and send it back.
    .htaccess turns foo.com/blah into foo.com/index.php?q=blah
    ...And PHP takes over.
  • Apache intercepts the request.
    Possibly routes it to other servers
    What folder should I look in for foo.com?
    Normally, it would then check /articles for a welcome.html file and send it back.
    .htaccess turns foo.com/blah into foo.com/index.php?q=blah
    ...And PHP takes over.
  • Apache intercepts the request.
    Possibly routes it to other servers
    What folder should I look in for foo.com?
    Normally, it would then check /articles for a welcome.html file and send it back.
    .htaccess turns foo.com/blah into foo.com/index.php?q=blah
    ...And PHP takes over.
  • Apache intercepts the request.
    Possibly routes it to other servers
    What folder should I look in for foo.com?
    Normally, it would then check /articles for a welcome.html file and send it back.
    .htaccess turns foo.com/blah into foo.com/index.php?q=blah
    ...And PHP takes over.
  • Bootstrap
    All page requests go through index.php (front-side controller)
    Bootstrap Drupal core, load essential includes
    What site am I running? connect to database
    Is there a cookie? Load the user.
    Now, ask for menu items...
  • Bootstrap
    All page requests go through index.php (front-side controller)
    Bootstrap Drupal core, load essential includes
    What site am I running? connect to database
    Is there a cookie? Load the user.
    Now, ask for menu items...
  • Bootstrap
    All page requests go through index.php (front-side controller)
    Bootstrap Drupal core, load essential includes
    What site am I running? connect to database
    Is there a cookie? Load the user.
    Now, ask for menu items...
  • Bootstrap
    All page requests go through index.php (front-side controller)
    Bootstrap Drupal core, load essential includes
    What site am I running? connect to database
    Is there a cookie? Load the user.
    Now, ask for menu items...
  • Bootstrap
    All page requests go through index.php (front-side controller)
    Bootstrap Drupal core, load essential includes
    What site am I running? connect to database
    Is there a cookie? Load the user.
    Now, ask for menu items...
  • The module
    Why, yes! Here&#x2019;s a list of all the URLs I can handle.
    Explain each line. See api.drupal.org
    This is called a hook. We&#x2019;ll get to this later.
  • The module
    Why, yes! Here&#x2019;s a list of all the URLs I can handle.
    Explain each line. See api.drupal.org
    This is called a hook. We&#x2019;ll get to this later.
  • Traffic Cop
    Is welcome.html an SEO-friendly alias? (about/welcome vs. welcome.html)
    Find the best match. (about)
    Run access checks.
    Call the function, passing along unused pieces of the path


  • Grunt work
    Module&#x2019;s function gets called. Extra params passed along.
    That&#x2019;s how node module works -- &#x2018;node&#x2019; plus a wildcard
    Can do anything now: print out JSON and exit(), etc.
    To build a normal page, build HTML and return it.
  • Grunt work
    Module&#x2019;s function gets called. Extra params passed along.
    That&#x2019;s how node module works -- &#x2018;node&#x2019; plus a wildcard
    Can do anything now: print out JSON and exit(), etc.
    To build a normal page, build HTML and return it.
  • Presentation
    Checks for 404, 403, and empty page.
    index.php now has the contents of the page.
    theme(&#x2018;page&#x2019;, $content)
    Sidebar blocks get loaded, the theme system is given a chance to add CSS and JS, etc.


  • Presentation
    Checks for 404, 403, and empty page.
    index.php now has the contents of the page.
    theme(&#x2018;page&#x2019;, $content)
    Sidebar blocks get loaded, the theme system is given a chance to add CSS and JS, etc.


  • Presentation
    Checks for 404, 403, and empty page.
    index.php now has the contents of the page.
    theme(&#x2018;page&#x2019;, $content)
    Sidebar blocks get loaded, the theme system is given a chance to add CSS and JS, etc.


  • Oh, look. Welcome.html!
    Apache gets back the fully rendered HTML. Sweet.
    Document gets fired back to the user.
    The user&#x2019;s browser renders it -- and they click on the next link and the process starts all over again.
  • Important detail: when drupal asked about menus and modules responded, we saw a hook.
    hooks are everywhere: when pieces of content load, when a db query is run, when a user logs in&#x2026;
    that&#x2019;s a drupal event. module_invoke_all(&#x2018;hook&#x2019;) => for modules()&#x2026; <name>_menu()
    Modules can create their own hooks just by calling module_invoke_all()
  • As a Drupal page is built, events are firing nonstop.
  • As a Drupal page is built, events are firing nonstop.
  • As a Drupal page is built, events are firing nonstop.
  • As a Drupal page is built, events are firing nonstop.
  • As a Drupal page is built, events are firing nonstop.
  • As a Drupal page is built, events are firing nonstop.
  • As a Drupal page is built, events are firing nonstop.
  • As a Drupal page is built, events are firing nonstop.
  • As a Drupal page is built, events are firing nonstop.












  • Hooks can announce what&#x2019;s going on
    Allow modules to answer questions
    Allow modules to extend functionality
    Allow modules to change existing workflows
  • Hooks can announce what&#x2019;s going on
    Allow modules to answer questions
    Allow modules to extend functionality
    Allow modules to change existing workflows
  • Hooks can announce what&#x2019;s going on
    Allow modules to answer questions
    Allow modules to extend functionality
    Allow modules to change existing workflows
  • Hooks can announce what&#x2019;s going on
    Allow modules to answer questions
    Allow modules to extend functionality
    Allow modules to change existing workflows
  • Hooks can announce what&#x2019;s going on
    Allow modules to answer questions
    Allow modules to extend functionality
    Allow modules to change existing workflows
  • What does &#x201C;hacking core&#x201D; mean?
    Why is it bad?
  • What does &#x201C;hacking core&#x201D; mean?
    Why is it bad?
























  • Drupal Development

    1. 1. Drupal Code: Day 1 where am i, and how did i get all these arrays
    2. 2. Hi. I’m eaton.
    3. 3. Drupal is... http://www.flickr.com/photos/druclimb/282597447/
    4. 4. Drupal is... Drupal Core http://www.flickr.com/photos/druclimb/282597447/
    5. 5. Drupal is... Node Drupal Core User http://www.flickr.com/photos/druclimb/282597447/
    6. 6. Drupal is... Views Five Star CCK Node Drupal Core User http://www.flickr.com/photos/druclimb/282597447/
    7. 7. Drupal is... Theme Views Five Star CCK Node Drupal Core User http://www.flickr.com/photos/druclimb/282597447/
    8. 8. Drupal is... Theme Views Five Star CCK Node Drupal Core User http://www.flickr.com/photos/druclimb/282597447/
    9. 9. name = Demo description = Just a simple demo module. core = 6.x function demo_nodeapi(&$node, $op) { global $user; if ($op == ‘view’) { if ($node->uid == $user->uid) { $node->title . ‘ [YOUR ARTICLE]’; } } } demo.info demo.module
    10. 10. name = Tricky description = A slightly trickier module. core = 6.x function tricky_form_alter(&form, $form_state, $id) { if ($id == ‘node_form’) { $title[‘#required’] = FALSE; } } function tricky_install() { drupal_set_message(‘You just installed Tricky!’); } tricky.info tricky.module tricky.install
    11. 11. views.info views.module views.inc user.inc node.inc blog.inc comment.inc ui.info ui.module arguments.inc handlers.inc filters.inc query.inc sprout.info sprout.module forum.inc views.pages.inc table.inc views.install sprout.install sprout.admin.inc sprout.inc CHANGELOG README
    12. 12. views.info views.module views.inc user.inc node.inc blog.inc comment.inc ui.info ui.module arguments.inc handlers.inc filters.inc query.inc sprout.info sprout.module forum.inc views.pages.inc table.inc views.install sprout.install sprout.admin.inc sprout.inc CHANGELOG README
    13. 13. views.info views.module views.inc user.inc node.inc blog.inc comment.inc ui.info ui.module arguments.inc handlers.inc filters.inc query.inc sprout.info sprout.module forum.inc views.pages.inc table.inc views.install sprout.install sprout.admin.inc sprout.inc CHANGELOG README
    14. 14. under the hood http://www.flickr.com/photos/sprakope/143770402/
    15. 15. I’d like welcome.html!
    16. 16. I’d like welcome.html!
    17. 17. I’ll go get that html file!
    18. 18. I’ll go get that html file!
    19. 19. I’ll go get that html file! .htaccess says to check… index.php?q=welcome.html
    20. 20. Index.php? I’ve got that.
    21. 21. Index.php? I’ve got that. bootstrap.inc menu.inc random mysql user
    22. 22. Here are all my URLs…
    23. 23. function mymodule_menu() { $items['about'] = array( 'title' => 'About us', 'description' => 'A description of us.', 'page callback' => 'mymodule_about', 'access arguments' => array('access content'), ); return $items; } Here are all my URLs…
    24. 24. function mymodule_menu() { $items['about'] = array( 'title' => 'About us', 'description' => 'A description of us.', 'page callback' => 'mymodule_about', 'access arguments' => array('access content'), ); return $items; } Here are all my URLs…
    25. 25. What’s the best match?
    26. 26. What’s the best match? Is welcome.html an alias? Does anyone handle the path? Does the user have access?
    27. 27. I’ll build the contents.
    28. 28. function mymodule_about($subpage = ‘legal’) { if ($subpage == ‘legal’) { return “We don’t have lawyers yet.”; } if ($subpage == ‘welcome’) { return “Welcome to our web site!”; } } I’ll build the contents.
    29. 29. function mymodule_about($subpage = ‘legal’) { if ($subpage == ‘legal’) { return “We don’t have lawyers yet.”; } if ($subpage == ‘welcome’) { return “Welcome to our web site!”; } } I’ll build the contents.
    30. 30. I’ll take that HTML...
    31. 31. I’ll take that HTML...
    32. 32. I’ll take that HTML...
    33. 33. I’ll take that HTML...
    34. 34. Here’s index.php… Eh, looks like welcome.html…
    35. 35. don’t use a hack. hook! http://www.flickr.com/photos/lanier67/185311136/
    36. 36. A list of content types A user is is being built registering A node is being Content is being displayed searched The menu is Links are being being built displayed The database is being queried A comment is being posted A form is being processed
    37. 37. module_invoke_all(‘foo’)
    38. 38. yourmodule_foo()
    39. 39. theirmodule_foo() mymodule_foo() yourmodule_foo() hismodule_foo() hermodule_foo()
    40. 40. function demo_nodeapi(&$node, $op) { global $user; if ($op == ‘view’ && $node->uid == $user->uid) { $node->title . ‘ [YOUR ARTICLE]’; } } function demo_form_alter(&form, $form_state, $id) { if ($id == ‘node_form’) { $title[‘#required’] = FALSE; } }
    41. 41. i
    42. 42. i ?
    43. 43. i ?
    44. 44. i ?
    45. 45. i All w i t h o u t h a ng ing Dr u p a l’s c o w n c o de ! ?
    46. 46. Don’t. Hack. Core.
    47. 47. Don’t. Hack. Core.
    48. 48. let’s see a module! http://www.flickr.com/photos/gonzales2010/8632116/
    49. 49. name = Birthday description = Wishes users a happy birthday. requirements[] = user core = 6.x
    50. 50. name = Birthday description = Wishes users a happy birthday. requirements[] = user core = 6.x
    51. 51. /** * Allows users to save their birthday, * and congratulates them on the big day. */ function birthday_menu() { $items['admin/settings/birthdays'] = array( 'title' => 'Birthday settings', 'description' => 'Settings for birthdays.', 'page callback' => 'birthday_page', 'access arguments' => array('administer users'), ); return $items; } function birthday_page() { return drupal_get_form('birthday_form'); }
    52. 52. /** * Allows users to save their birthday, * and congratulates them on the big day. */ function birthday_menu() { $items['admin/settings/birthdays'] = array( 'title' => 'Birthday settings', 'description' => 'Settings for birthdays.', 'page callback' => 'birthday_page', 'access arguments' => array('administer users'), ); return $items; } function birthday_page() { return drupal_get_form('birthday_form'); }
    53. 53. function birthday_form() { $form['birthday_age'] = array( '#type' => 'checkbox', '#title' => t(quot;Show users how old they are.quot;), '#default_value' => variable_get('age', TRUE), ); $form['submit'] = array( '#type' => 'submit', '#value' => t('Save settings'), ); return $form; } function birthday_form_submit($form, $form_state) { $values = $form_state['values']; variable_set('age', $values['birthday_age']); drupal_set_message(t('Birthday settings saved.')); }
    54. 54. function birthday_form() { $form['birthday_age'] = array( '#type' => 'checkbox', '#title' => t(quot;Show users how old they are.quot;), '#default_value' => variable_get('age', TRUE), ); $form['submit'] = array( '#type' => 'submit', '#value' => t('Save settings'), ); return $form; } function birthday_form_submit($form, $form_state) { $values = $form_state['values']; variable_set('age', $values['birthday_age']); drupal_set_message(t('Birthday settings saved.')); }
    55. 55. function birthday_user($op, &$edit, &$account) { if ($op == 'view' && $day = $account->birthday) { $timestamp = mktime(0, 0, 0, $day['month'], $day['day'], $day['year']); $account->content['birthday'] = array( '#type' => 'item', '#title' => t('Birthday'), '#value' => date('l, F jS, Y', $timestamp)); } elseif ($op == 'form') { $form['birthday'] = array( '#type' => 'date', '#title' => t('Birthday'), '#default_value' => $account->birthday); return $form; } }
    56. 56. function birthday_user($op, &$edit, &$account) { if ($op == 'view' && $day = $account->birthday) { $timestamp = mktime(0, 0, 0, $day['month'], $day['day'], $day['year']); $account->content['birthday'] = array( '#type' => 'item', '#title' => t('Birthday'), '#value' => date('l, F jS, Y', $timestamp)); } elseif ($op == 'form') { $form['birthday'] = array( '#type' => 'date', '#title' => t('Birthday'), '#default_value' => $account->birthday); return $form; } }
    57. 57. function birthday_user($op, &$edit, &$account) { if ($op == 'view' && $day = $account->birthday) { $timestamp = mktime(0, 0, 0, $day['month'], $day['day'], $day['year']); $account->content['birthday'] = array( '#type' => 'item', '#title' => t('Birthday'), '#value' => date('l, F jS, Y', $timestamp)); } elseif ($op == 'form') { $form['birthday'] = array( '#type' => 'date', '#title' => t('Birthday'), '#default_value' => $account->birthday); return $form; } }
    58. 58. function birthday_block($op = 'list') { global $user; if ($op == 'list') { $block['congrats']['info'] = t('Birthday'); return $block; } elseif ($op == 'view' && $day = $user->birthday) { if ($day['month']==date('n') && $day['day']==date('j')) { $message = t(quot;It's your birthday! it's your birthday!quot;); if (variable_get('age', TRUE)) { $age = date('Y') - $day['year']; $message .= t(quot; You're %age.quot;, array('%age' => $age)); } $block['subject'] = t('Happy birthday!'); $block['content'] = $message . birthday_song(); return $block; } } }
    59. 59. function birthday_block($op = 'list') { global $user; if ($op == 'list') { $block['congrats']['info'] = t('Birthday'); return $block; } elseif ($op == 'view' && $day = $user->birthday) { if ($day['month']==date('n') && $day['day']==date('j')) { $message = t(quot;It's your birthday! it's your birthday!quot;); if (variable_get('age', TRUE)) { $age = date('Y') - $day['year']; $message .= t(quot; You're %age.quot;, array('%age' => $age)); } $block['subject'] = t('Happy birthday!'); $block['content'] = $message . birthday_song(); return $block; } } }
    60. 60. function birthday_block($op = 'list') { global $user; if ($op == 'list') { $block['congrats']['info'] = t('Birthday'); return $block; } elseif ($op == 'view' && $day = $user->birthday) { if ($day['month']==date('n') && $day['day']==date('j')) { $message = t(quot;It's your birthday! it's your birthday!quot;); if (variable_get('age', TRUE)) { $age = date('Y') - $day['year']; $message .= t(quot; You're %age.quot;, array('%age' => $age)); } $block['subject'] = t('Happy birthday!'); $block['content'] = $message . birthday_song(); return $block; } } }
    61. 61. function birthday_song() { $path = drupal_get_path('module', 'birthday'); $path .= '/birthday.mid '; $output = '<embed src=quot;' . $path . 'quot;; $output .= ' autostart=quot;truequot; loop=quot;truequot;'; $output .= ' width=quot;2quot; height=quot;0quot;></embed>'; return $output; }
    62. 62. function birthday_song() { $path = drupal_get_path('module', 'birthday'); $path .= '/birthday.mid '; $output = '<embed src=quot;' . $path . 'quot;; $output .= ' autostart=quot;truequot; loop=quot;truequot;'; $output .= ' width=quot;2quot; height=quot;0quot;></embed>'; return $output; }
    63. 63. http://www.flickr.com/photos/thomashawk/2681744739
    64. 64. drupal manages the page http://www.flickr.com/photos/thomashawk/2681744739
    65. 65. drupal manages the page modules build the content http://www.flickr.com/photos/thomashawk/2681744739
    66. 66. drupal manages the page modules build the content modules also respond to events http://www.flickr.com/photos/thomashawk/2681744739
    67. 67. drupal manages the page modules build the content modules also respond to events hack with hooks http://www.flickr.com/photos/thomashawk/2681744739
    68. 68. api.drupal.org tinyurl.com/drupal-code tinyurl.com/drupal-kickstart tinyurl.com/drupal-rocking
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×