I've been reading alot on this site about module development, trying to teach myself how to develop modules (duh), and it is very confusing to me, it feels like topics either jump all over the place, or I'm missing some knowledge or skill that everyone else has, and I don't :(
I've done the tutorial for "On This Day" example module, which is very simple. Now I'm trying to do some more advanced things, but I'm getting hung up on creating a default theme for a module.
I'm having a problem understanding why data stored as arrays inside other arrays. This is probably a PHP knowledge question, not exactly a drupal question, but I am asking for help so I can understand Drupal better.
in some example code from the Book Module:
/**
* Implementation of hook_theme()
*/
function book_theme() {
return array(
'book_navigation' => array(
'arguments' => array('book_link' => NULL),
'template' => 'book-navigation',
),
'book_export_html' => array(
'arguments' => array('title' => NULL, 'contents' => NULL, 'depth' => NULL),
'template' => 'book-export-html',
),
...etc...it first creates an array with the key 'book_navigation' and sets it's value as an array, and that array has another array inside of it !
why does it do this?
My guess is that you have to pass information to functions, if you have more than 1 item to pass, then you put them into an array.
1 item in that array can have multiple items, so it is an array inside an array ( a multi-dimensional array, like a spreadsheet of data)
Is my explanation to myself correct, or could it be improved so I understand it better?
I understand an array to be a series of information, separated by commas i.e. (red, blue, green).
just like from the example I pasted above:
array('title' => NULL, 'contents' => NULL, 'depth' => NULL)
I understand this is refered to as an associative array, because it has keys for the values, i.e. the key 'title', has the value of NULL. It is easier to use associative arrays than trying to remember how to refer to the element in the array by it's index 0,1,2, etc.
But then the code shows something like this and I'm confused.
array('book_link' => NULL)
Why is that an array if it only has 1 element?
Is the element with the key 'book_link' going to have more than 1 value, therefore it must be declared as an array?
Is it just infered to be that way, or is this something I learn with practice?
Is there an easier way to read the code when I see arrays inside arrays, or does it just take time to "see" the code, sort of like it takes time and practice to be able to read music as fast as reading regular text?
I don't want to make this too long, so I'll stop here and look forward to your help in understanding this better. Thanks.
Comments
Think in terms of data
Think in terms of data structures that happens to be an array.
The hook_theme() function is expected to return an array of theme hooks, indexed by the internal name of the hook. Each element of that array is an array that describes the theme hook, you can read about the possible elements at hook_theme(). Some of those elements like ''arguments' are expected to be an array of elements, so for example array('book_link' => NULL) says we expect on argument, 'book_link' and the default value is NULL.
There's famous saying that if
There's famous saying that if your only tool is a hammer, every problem starts to look like a nail...
PHP has only one basic data structure (I'm going to sweep object under the rug for this post) and that is the array. So, whenever you have data with structure to it, it ends up as an array in PHP. So far, good. But, as you said already, an array is basically a list. It can be a simple ordered list
array('red', 'green', 'blue')or it can be a keyed listarray('necktie' => 'red', 'shirt' => 'green', 'pants' =. 'blue'). (Please don't mention this to the fashion police...)So what if your data has more structure than that? You might have a hierarchy of information, a page has regions, which have blocks, which have titles and content. How do you fit that into an array? You can't, because there's more structure here than a list has. What you can do is fit it into arrays, step by step:
$page = array'left sidebar' => //Stuff for the left sidebar goes here.
'right sidebar' => //etc.
);
The left sidebar might be a banner and the navigation menu, like so:
array('banner' => //banner block info goes here.
'navigation' = //navigation menu info goes here.
);
The banner block in turn would be something like:
array('title' => NULL,
'content' => '<img src="mybanner.jpg" />',
);
Notice the NULL to indicate the block shouldn't have a title. Now, if you put all of this together, you end up with:
$page = array'left sidebar' => array(
'banner' => array(
'title' => NULL,
'content' => '<img src="mybanner.jpg" />',
),
'navigation' = //navigation menu info goes here.
),
'right sidebar' => //etc.
);
Which is arrays inside arrays. Because PHP will let you create arbitrarily deep nestings of arrays (arrays inside arrays inside arrays inside ...), this is an extremely flexible way of putting information together and indicating how it all relates to each other. Drupal uses it in many places, so it is well worth studying and playing around with. For example, express your family tree as in PHP as nested arrays. Once you get the hang of the concept, you'll find a lot of Drupal code a lot easier to understand.
As for your last two questions: Something might be an array with just one element because the function that processes that information is capable of handling more than one element. That means the function needs an array.
And the easiest way to understand such a structure is one level at a time. You can either do what I did and start at the top and then work your way down, or you can start at the bottom and work your way up. Whatever you think is easier. The important thing is ignore everything except the part of the structure you are looking at. Once you understand that part, move to the next.
Enjoy!
thanks for that excellent explanation.
It has started to sink in, the more I look at this.
For example, the translate function
t( 'some text with a %variable', array( '%variable' => 'adjustable value' ) ) ;
it has 2 arguments, each separated by a comma.
the 2nd argument needs to be an array, because there is no way to forsee how many variable tokens (the %variable parts) the programmer might put in the first argument (the part to be translated). So the 2nd argument is an array, and for each element of the array, you would have key => value pairs, and separate each of those with a comma.
so i just look up that function in the API reference, and learn what type of data it is looking for for that argument, and if it has to be an array, just prefix it with the phrase " array( "
ok that makes sense.
thanks for your help
Thanks ... It should be added to the handbook
Thanks for the great explanation - I believe it should be added to the handbook.