Developing for Drupal

The Drupal engine is open source. It is possible for each and every user to become a contributor. The fact remains that most Drupal users, even those skilled in programming arts, have never contributed to Drupal even though most of us had days where we thought to ourselves: "I wish Drupal could do this or that ...". Through this section, we hope to make Drupal more accessible to them.

The guide pages found here are collaborative, but not linked to particular Drupal versions. Because of this, documentation can become out of date. To combat this, we are moving most developer documentation into the Doxygen documentation that is versioned by CVS and generated from the source code. Look there for up-to-date and version-specific information.

What about upgrading and backwards compatability? For more details read this overview of the Drupal's philosophy on backwards compatibility

Contributing to Development

Drupal is a collaborative, community-driven project. This means that the software and its supporting features (documentation, the drupal.org website) are collaboratively produced by users and developers all over the world.

There are several ways to contribute to Drupal:

This section focuses on the first of these three.

Types of Contributions

There are two basic types of contributions you can make to Drupal's code base: (a) "contributed" modules or themes and (b) contributions to the drupal "core".

  • The easiest way to help is simply to find a bug or feature request that you want to fix, modify a local copy of the code to fix that problem, create a patch file of your changes, and then attach the patch to an issue for that bug or feature request
  • "Contributed modules" are the community-produced modules and themes available on the Drupal site.  To make a contribution, you need
  • As long as contributions meet some minimal criteria - they do what they claim to and have some demonstrable benefit without unduly replicating already-available functionality, and are coded with an eye towards secure code - they should be ok.
  • You should also read about maintaining a project on Drupal.org and consider joining forces with others to avoid duplication of effort and share the load of your module.
  • If you have major enhancements you wish to contribute, doing so via a contributed module is in many ways the easiest way to begin.  Contributed code has a relatively low set of requirements to meet. It also helps to trial the feature with the community, gain feedback and help the code mature.
  • Your code contribution is welcome. Consider also being a responsible maintainer and helping build a community around your module as it grows in use and popularity. This will help reduce your load as well.
  • In contrast, changes to the Drupal core are made through a thorough consultative process to ensure the overall integrity of the software.

    Changes to the Drupal core are generally of three types:

    • Bug fixes These changes respond to identified problems in
      the existing code.
    • New features These changes are enhancements on what is already available.
    • Code maintenance.  These changes are to improve the quality of the code or bring it up to date with changes elsewhere in Drupal.  This can include bringing code in line with coding standards, improving efficiency (e.g., eliminating unneeded database queries), introducing or improving in-line comments, and doing upgrades for compliance with a new release version.

    While you can create your own issues, you can also begin by simply taking on existing tasks on the task list. See the page "Tips for contributing to the core" for advice on how to get started as a core contributor.

Task list

The Drupal bug database contains many issues classified as "bite-sized" tasks -- tasks that are well-defined and self-contained, and thus suitable for a volunteer looking to get involved with the project. You don't need broad or detailed knowledge of Drupal's design to take on one of these, just a pretty good idea of how things generally work, and familiarity with the coding guidelines. Each task is something a volunteer could pick off in a spare evening or two.

If you start one of these, please update the task and assign it to yourself, so no one else duplicates your effort. Once the task is complete, you can attach a patch that includes your changes into the issue, and set the status to "patch (code needs review)".

Bug reports

Your bug reports play an essential role in making Drupal reliable. If you find a bug, please follow the submission guidelines in this handbook. If you can, it is also helpful to provide a patch that fixes your bug. If you can't provide a patch, hopefully someone else will be able to fix the bug.

Bug reports can be posted in connection with any project hosted on drupal.org. You can submit a new bug via the submit issue form. Provide a sensible title for the bug, and choose the project you think you have found the bug in. After previewing the submission, you will need to choose a related component and you will be able to provide more details about the bug, including the description of the problem itself. Please include any error messages you received and a detailed description of what you were doing at the time.

Note that you DO have to be a logged in member of drupal.org to submit bugs.

Bugs are fixed in Drupal almost every day, often many bugs are fixed in a day. Therfore it is important that you are using the latest version of Drupal and that your bug still hapens in that version.

It is frequently helpful to include the PHP, database and webserver version information.

More detailed advice on submitting high quality bugs and getting them fixed quickly is available in this handbook. Read the next pages for more details.

How to report bugs effectively

Summary

  • The first aim of a bug report is to let the programmer see the failure with their own eyes. If you can't be with them to make it fail in front of them, give them detailed instructions so that they can make it fail for themselves.
  • In case the first aim doesn't succeed, and the programmer can't see it failing themselves, the second aim of a bug report is to describe what went wrong. Describe everything in detail. State what you saw, and also state what you expected to see. Write down the error messages, especially if they have numbers in.
  • When your computer does something unexpected, freeze. Do nothing until you're calm, and don't do anything that you think might be dangerous.
  • By all means try to diagnose the fault yourself if you think you can, but if you do, you should still report the symptoms as well.
  • Be ready to provide extra information if the programmer needs it. If they didn't need it, they wouldn't be asking for it. They aren't being deliberately awkward. Have version numbers at your fingertips, because they will probably be needed.
  • Write clearly. Say what you mean, and make sure it can't be misinterpreted.
  • Above all, be precise. Programmers like precision.

Introduction
Anybody who has written software for public use will probably have received at least one bad bug report. Reports that say nothing ("It doesn't work!"); reports that make no sense; reports that don't give enough information; reports that give wrong information. Reports of problems that turn out to be user error; reports of problems that turn out to be the fault of somebody else's program; reports of problems that turn out to be network failures.

There's a reason why technical support is seen as a horrible job to be in, and that reason is bad bug reports. However, not all bug reports are unpleasant: I maintain free software, when I'm not earning my living, and sometimes I receive wonderfully clear, helpful, informative bug reports.

In this essay I'll try to state clearly what makes a good bug report. Ideally I would like everybody in the world to read this essay before reporting any bugs to anybody. Certainly I would like everybody who reports bugs to me to have read it.

In a nutshell, the aim of a bug report is to enable the programmer to see the program failing in front of them. You can either show them in person, or give them careful and detailed instructions on how to make it fail. If they can make it fail, they will try to gather extra information until they know the cause. If they can't make it fail, they will have to ask you to gather that information for them.

In bug reports, try to make very clear what are actual facts ("I was at the computer and this happened") and what are speculations ("I think the problem might be this"). Leave out speculations if you want to, but don't leave out facts.

When you report a bug, you are doing so because you want the bug fixed. There is no point in swearing at the programmer or being deliberately unhelpful: it may be their fault and your problem, and you might be right to be angry with them, but the bug will get fixed faster if you help them by supplying all the information they need. Remember also that if the program is free, then the author is providing it out of kindness, so if too many people are rude to them then they may stop feeling kind.

"It doesn't work."
Give the programmer some credit for basic intelligence: if the program really didn't work at all, they would probably have noticed. Since they haven't noticed, it must be working for them. Therefore, either you are doing something differently from them, or your environment is different from theirs. They need information; providing this information is the purpose of a bug report. More information is almost always better than less.

Many programs, particularly free ones, publish their list of known bugs. If you can find a list of known bugs, it's worth reading it to see if the bug you've just found is already known or not. If it's already known, it probably isn't worth reporting again, but if you think you have more information than the report in the bug list, you might want to contact the programmer anyway. They might be able to fix the bug more easily if you can give them information they didn't already have.

This essay is full of guidelines. None of them is an absolute rule. Particular programmers have particular ways they like bugs to be reported. If the program comes with its own set of bug-reporting guidelines, read them. If the guidelines that come with the program contradict the guidelines in this essay, follow the ones that come with the program!

If you are not reporting a bug but just asking for help using the program, you should state where you have already looked for the answer to your question. ("I looked in chapter 4 and section 5.2 but couldn't find anything that told me if this is possible.") This will let the programmer know where people will expect to find the answer, so they can make the documentation easier to use.

"Show me"
One of the very best ways you can report a bug is by showing it to the programmer. Stand them in front of your computer, fire up their software, and demonstrate the thing that goes wrong. Let them watch you start the machine, watch you run the software, watch how you interact with the software, and watch what the software does in response to your inputs.

They know that software like the back of their hand. They know which parts they trust, and they know which parts are likely to have faults. They know intuitively what to watch for. By the time the software does something obviously wrong, they may well have already noticed something subtly wrong earlier which might give them a clue. They can observe everything the computer does during the test run, and they can pick out the important bits for themselves.

This may not be enough. They may decide they need more information, and ask you to show them the same thing again. They may ask you to talk them through the procedure, so that they can reproduce the bug for themselves as many times as they want. They might try varying the procedure a few times, to see whether the problem occurs in only one case or in a family of related cases. If you're unlucky, they may need to sit down for a couple of hours with a set of development tools and really start investigating. But the most important thing is to have the programmer looking at the computer when it goes wrong. Once they can see the problem happening, they can usually take it from there and start trying to fix it.

"Show me how to show myself"
This is the era of the Internet. This is the era of worldwide communication. This is the era in which I can send my software to somebody in Russia at the touch of a button, and he can send me comments about it just as easily. But if he has a problem with my program, he can't have me standing in front of it while it fails. "Show me" is good when you can, but often you can't.

If you have to report a bug to a programmer who can't be present in person, the aim of the exercise is to enable them to reproduce the problem. You want the programmer to run their own copy of the program, do the same things to it, and make it fail in the same way. When they can see the problem happening in front of their eyes, then they can deal with it.

So tell them exactly what you did. If it's a graphical program, tell them which buttons you pressed and what order you pressed them in. If it's a program you run by typing a command, show them precisely what command you typed. Wherever possible, you should provide a verbatim transcript of the session, showing what commands you typed and what the computer output in response.

Give the programmer all the input you can think of. If the program reads from a file, you will probably need to send a copy of the file. If the program talks to another computer over a network, you probably can't send a copy of that computer, but you can at least say what kind of computer it is, and (if you can) what software is running on it.

"Works for me, so what goes wrong?"
If you give the programmer a long list of inputs and actions, and they fire up their own copy of the program and nothing goes wrong, then you haven't given them enough information. Possibly the fault doesn't show up on every computer; your system and theirs may differ in some way. Possibly you have misunderstood what the program is supposed to do, and you are both looking at exactly the same display but you think it's wrong and they know it's right.

So also describe what happened. Tell them exactly what you saw. Tell them why you think what you saw is wrong; better still, tell them exactly what you expected to see. If you say "and then it went wrong", you have left out some very important information.

If you saw error messages then tell the programmer, carefully and precisely, what they were. They are important! At this stage, the programmer is not trying to fix the problem: they're just trying to find it. They need to know what has gone wrong, and those error messages are the computer's best effort to tell you that. Write the errors down if you have no other easy way to remember them, but it's not worth reporting that the program generated an error unless you can also report what the error message was.

In particular, if the error message has numbers in it, do let the programmer have those numbers. Just because you can't see any meaning in them doesn't mean there isn't any. Numbers contain all kinds of information that can be read by programmers, and they are likely to contain vital clues. Numbers in error messages are there because the computer is too confused to report the error in words, but is doing the best it can to get the important information to you somehow.

At this stage, the programmer is effectively doing detective work. They don't know what's happened, and they can't get close enough to watch it happening for themselves, so they are searching for clues that might give it away. Error messages, incomprehensible strings of numbers, and even unexplained delays are all just as important as fingerprints at the scene of a crime. Keep them!

If you are using Unix, the program may have produced a core dump. Core dumps are a particularly good source of clues, so don't throw them away. On the other hand, most programmers don't like to receive huge core files by e-mail without warning, so ask before mailing one to anybody. Also, be aware that the core file contains a record of the complete state of the program: any "secrets" involved (maybe the program was handling a personal message, or dealing with confidential data) may be contained in the core file.

"So then, I tried..."
There are a lot of things you might do when an error or bug comes up. Many of them make the problem worse. A friend of mine at school deleted all her Word documents by mistake, and before calling in any expert help, she tried reinstalling Word, and then she tried running Defrag. Neither of these helped recover her files, and between them they scrambled her disk to the extent that no Undelete program in the world would have been able to recover anything. If she'd only left it alone, she might have had a chance.

Users like this are like a mongoose backed into a corner: with its back to the wall and seeing certain death staring it in the face, it attacks frantically, because doing something has to be better than doing nothing. This is not well adapted to the type of problems computers produce.

Instead of being a mongoose, be an antelope. When an antelope is confronted with something unexpected or frightening, it freezes. It stays absolutely still and tries not to attract any attention, while it stops and thinks and works out the best thing to do. (If antelopes had a technical support line, it would be telephoning it at this point.) Then, once it has decided what the safest thing to do is, it does it.

When something goes wrong, immediately stop doing anything. Don't touch any buttons at all. Look at the screen and notice everything out of the ordinary, and remember it or write it down. Then perhaps start cautiously pressing "OK" or "Cancel", whichever seems safest. Try to develop a reflex reaction - if a computer does anything unexpected, freeze.

If you manage to get out of the problem, whether by closing down the affected program or by rebooting the computer, a good thing to do is to try to make it happen again. Programmers like problems that they can reproduce more than once. Happy programmers fix bugs faster and more efficiently.

"I think the tachyon modulation must be wrongly polarised."
It isn't only non-programmers who produce bad bug reports. Some of the worst bug reports I've ever seen come from programmers, and even from good programmers.

I worked with another programmer once, who kept finding bugs in his own code and trying to fix them. Every so often he'd hit a bug he couldn't solve, and he'd call me over to help. "What's gone wrong?" I'd ask. He would reply by telling me his current opinion of what needed to be fixed.

This worked fine when his current opinion was right. It meant he'd already done half the work and we were able to finish the job together. It was efficient and useful.

But quite often he was wrong. We would work for some time trying to figure out why some particular part of the program was producing incorrect data, and eventually we would discover that it wasn't, that we'd been investigating a perfectly good piece of code for half an hour, and that the actual problem was somewhere else.

I'm sure he wouldn't do that to a doctor. "Doctor, I need a prescription for Hydroyoyodyne." People know not to say that to a doctor: you describe the symptoms, the actual discomforts and aches and pains and rashes and fevers, and you let the doctor do the diagnosis of what the problem is and what to do about it. Otherwise the doctor dismisses you as a hypochondriac or crackpot, and quite rightly so.

It's the same with programmers. Providing your own diagnosis might be helpful sometimes, but always state the symptoms. The diagnosis is an optional extra, and not an alternative to giving the symptoms. Equally, sending a modification to the code to fix the problem is a useful addition to a bug report but not an adequate substitute for one.

If a programmer asks you for extra information, don't make it up! Somebody reported a bug to me once, and I asked him to try a command that I knew wouldn't work. The reason I asked him to try it was that I wanted to know which of two different error messages it would give. Knowing which error message came back would give a vital clue. But he didn't actually try it - he just mailed me back and said "No, that won't work". It took me some time to persuade him to try it for real.

Using your intelligence to help the programmer is fine. Even if your deductions are wrong, the programmer should be grateful that you at least tried to make their life easier. But report the symptoms as well, or you may well make their life much more difficult instead.

"That's funny, it did it a moment ago."
Say "intermittent fault" to any programmer and watch their face fall. The easy problems are the ones where performing a simple sequence of actions will cause the failure to occur. The programmer can then repeat those actions under closely observed test conditions and watch what happens in great detail. Too many problems simply don't work that way: there will be programs that fail once a week, or fail once in a blue moon, or never fail when you try them in front of the programmer but always fail when you have a deadline coming up.

Most intermittent faults are not truly intermittent. Most of them have some logic somewhere. Some might occur when the machine is running out of memory, some might occur when another program tries to modify a critical file at the wrong moment, and some might occur only in the first half of every hour! (I've actually seen one of these.)

Also, if you can reproduce the bug but the programmer can't, it could very well be that their computer and your computer are different in some way and this difference is causing the problem. I had a program once whose window curled up into a little ball in the top left corner of the screen, and sat there and sulked. But it only did it on 800x600 screens; it was fine on my 1024x768 monitor.

The programmer will want to know anything you can find out about the problem. Try it on another machine, perhaps. Try it twice or three times and see how often it fails. If it goes wrong when you're doing serious work but not when you're trying to demonstrate it, it might be long running times or large files that make it fall over. Try to remember as much detail as you can about what you were doing to it when it did fall over, and if you see any patterns, mention them. Anything you can provide has to be some help. Even if it's only probabilistic (such as "it tends to crash more often when Emacs is running"), it might not provide direct clues to the cause of the problem, but it might help the programmer reproduce it.

Most importantly, the programmer will want to be sure of whether they're dealing with a true intermittent fault or a machine-specific fault. They will want to know lots of details about your computer, so they can work out how it differs from theirs. A lot of these details will depend on the particular program, but one thing you should definitely be ready to provide is version numbers. The version number of the program itself, and the version number of the operating system, and probably the version numbers of any other programs that are involved in the problem.

"So I loaded the disk on to my Windows . . ."
Writing clearly is essential in a bug report. If the programmer can't tell what you meant, you might as well not have said anything.

I get bug reports from all around the world. Many of them are from non-native English speakers, and a lot of those apologise for their poor English. In general, the bug reports with apologies for their poor English are actually very clear and useful. All the most unclear reports come from native English speakers who assume that I will understand them even if they don't make any effort to be clear or precise.

  • Be specific. If you can do the same thing two different ways, state which one you used. "I selected Load" might mean "I clicked on Load" or "I pressed Alt-L". Say which you did. Sometimes it matters.
  • Be verbose. Give more information rather than less. If you say too much, the programmer can ignore some of it. If you say too little, they have to come back and ask more questions. One bug report I received was a single sentence; every time I asked for more information, the reporter would reply with another single sentence. It took me several weeks to get a useful amount of information, because it turned up one short sentence at a time.
  • Be careful of pronouns. Don't use words like "it", or references like "the window", when it's unclear what they mean. Consider this: "I started FooApp. It put up a warning window. I tried to close it and it crashed." It isn't clear what the user tried to close. Did they try to close the warning window, or the whole of FooApp? It makes a difference. Instead, you could say "I started FooApp, which put up a warning window. I tried to close the warning window, and FooApp crashed." This is longer and more repetitive, but also clearer and less easy to misunderstand.
  • Read what you wrote. Read the report back to yourself, and see if you think it's clear. If you have listed a sequence of actions which should produce the failure, try following them yourself, to see if you missed a step.

HOWTO: Help with QA - OR - What to do when you find a bug

This set of pages is intented for two different types of users who need to get an issue resolved. It helps users understand the Drupal issue (bug) tracking system.

You want to give back to drupal without programming

The first is the situation where you are not a programmer, but you want to help with Drupal in some way. That's great! Ideally every user of Drupal would provide some assistance, though not all are able to write PHP. This guide can help you to give back to the community and help others. While there are many ways to help Drupal, this is one very important and often neglected way.

In this case, the set of "Contributor Links" available in your profile page are very handy in providing the bug bingo system which will take you to a random bug in the issue queue. If you have 10 extra minutes, spend some time clicking on "bug bingo" and see if you can improve the issue reports that you find so they are more clear.

You've been bitten by a bug and want it fixed

Eventually it happens to everyone - a bug "bites" you. That is to say, you find a problem with the way that Drupal works. This can be very frustrating. You want your bug fixed and fast, but either you aren't a programmer or you aren't savvy enough to write the code to fix this particular bug. You need help from someone else to get your bug fixed. How can you do that?

Ultimate Goal: Helping the Developers

Whichever reason you have for writing bugs or working on the issue queue your goal is simple: help the developers. Realistically there is a relative scarcity of people who can write good code. If you help make good issue reports and improve the current issues by following the advice laid out in this set of pages, you will not only make the developer's job easier you will also learn a lot about how Drupal works and will grow in your knowledge of development and coding practices. Working on issues is a great way to work your way into becoming a Drupal developer. After you have improved a few issues and started to provide minor patches you can then move onto more major changes. Proper use of the issue queue brings you respect from other users and developers who will then go out of their way to help you.

Getting a Bug Fixed Sooner

Let's say that you found a bug that affects you, you searched for it and found that it's already submitted. Now you want to ensure that it gets fixed. Here are a couple things you can do to improve the likelihood of the bug getting attention from a developer.

Improving Bug Reports

Many bug reports don't get attention simply because the quality of the report is low making it harder to understand and work on the bug. It will help the developer tremendously if you can take these bugs and improve them so that they have enough information. If necessary, ask questions of the original reporter. Try to repeat the problem yourself and note and differences or similarities in the results and the system configurations. If a developer sees a bug with a clear report that has been repeated then it is much easier for them to fix it.

In addition validating the description, make sure that the status, version, priority, and other values are set correctly.

Increase Visibility of the Issue

Once you have already ensured that the issue is well documented, repeatable, and properly categorized, it's important to make sure that people are aware of the issue. Many times an issue only affects a subset of the population so a developer who might be able to fix your bug might not be aware of it. Several easy ways to help increase the visibility of a particular bug is the write about it in your blog, join #drupal-support on IRC and ask around about the bug, add the bug to your email signature on the account that you use for the mailing lists or to your Drupal.org signature and then be sure to provide lots of help in the forum and the mailing lists so your signature is visible.

How not to increase visibility: send private emails to the module owner. If they are the owner they've probably already seen the bug via email from the issue tracker so another email is just a waste of time to them.

Providing a Patch

Many times the bug report will contain a description of what to change or will have the text of a patch pasted into the bug. While it may seem trivial, a patch makes the maintainer's job easier than just describing the change or pasting the patch into the comments of the bug.

If you can write the necessary code - by all means, create a patch. Again, it makes the maintainer's life simpler if someone creates a patch and all

Improving a Patch

Many times a patch exists but does not conform to Drupal's coding standards or lacks in some other ways. You can help to review the patch and ensure that it conforms to the coding standards. This is relatively advanced for someone who doesn't know how to program PHP, but it isn't terribly difficult and helps you understand how Drupal works.

Hire Someone or Providing a Bounty

Many times a bug just needs a bounty. Putting out some money on a bug (or getting others to join together to create a big bounty) can result in the quick resolution. Sometimes you just need a solution now. In that case, take a look at the Support and Professional Services page in the handbook to try and find someone who might be interested. You can also read the HOWTO: Hire a Drupal site developer to help you in finding the right person.

Ineffective Methods of Getting a Bug Fixed
  • Marking a "closed" or "won't fix" bug as active again without providing a convincing argument as to why it should be opened again. It's better off to provide the convincing argument and let someone else reopen the bug
HOWTO: Make A GOOD issue report

Drupal makes use of the Drupal Project Module to keep track of issues that are found in Drupal Core software, Modules, Themes, Theme Engines, and Translations. This system tracks several pieces of information about each issue but also leaves a large empty box for you to enter your own bug report. If you want your bug to get fixed, it is extremely important that you take the time to enter the proper information into these fields.

You should also see How to troubleshoot Drupal for self-help steps to do BEFORE raising an issue.

Project Information

Make sure you choose the correct version and make a decent guess as to the right Project and Component. Sometimes the correct value can be unclear, but if you make an effort to get it right that helps.

Issue Information

Try to determine the Category, Priority, Assigned, and Status values.

Category: Bug Reports are for situations where the software does not work as was intended by the programmer. Feature Requests are for situations where the software works as designed, but the design can be improved. Tasks are for something that just needs to get done [frankly their use seems a little unclear]. Support Requests are for situations where you wish to ask about a specific component. Support Requests can seem redundant with the forums, IRC, and mailing lists, but these are a good way to ask a question at a targeted audience (the module maintainer).

Note that new features are generally only accepted for the CVS version of code unless they are very important. Even if it seems important to you, it has to be important for a large number of sites to be worth creating a fix for a currently released version of Drupal. You cannot get around this rule by simply labeling a feature request as a bug request. If you want to get a feature applied to a released version of Drupal you need to make the case that it is important, affects a large number of sites, and ensure that the code changed is stable.

Priority: the priority field is an easy one to abuse. Generally, Critical should be reserved for the most problematic and important issues. Abuse of the Critical field will likely get your issue ignored by a developer and that's the last thing you want. Normal and Minor priorities are both fine to use. More detail in Priority Levels of Issues.

Assigned: the Assigned field helps keep track of the person working on a particular issue. If you are working on the issue - e.g. you are writing a patch to fix it - then you should set the issue as assigned to you.

Status: Status is one of the most often overlooked fields. Many developers have filters set to look for issues in certain statuses, so changing this field inappropriately can lead to your issue getting ignored.

Issue Details

Title: you want your title to be descriptive and concise. Compare these two titles:
SITE BROKEN YOU MUST FIX NOW!!!111!!

and

Admin-Modules Page Blank After Installing Module Foo

The first title doesn't explain the problem and tries to impart a sense of priority. The priority should stay in the priority field. The title is for describing your problem, and while "SITE BROKEN" may be what you think of your site it doesn't help a developer when they see three bug reports with different problems all with the title "SITE BROKEN". The second title succinctly describes the specific problem with the site and a possible cause. This makes it easy for the developer to keep track of the bugs in their queue. If you look at many of the issue queues you will see dozens or hundreds of issues. Having unique titles that are descriptive makes a specific issue stand out as easier to work on among the rest of the issues.

Also note that the project issue titles do not behave like a forum thread. Changing the title will change the title of the whole issue, not just your followup. This is useful for renaming a vague issue into a more descriptive one but it makes things worse if it is used to title issues like "I'm getting this too".

Description: The Description field is wide open which leaves you a lot of space to say a lot or a little. The Description takes the title one step further. Generally speaking, the majority of the time spent fixing an issue is spent on understanding the problem and finding the cause of that issue. The goal of the description is to state the exact set of conditions that cause a problem and the resultant undesirable state of the system so that the developer spends as little time as possible understanding your situation. Your issue should reflect the

  • repeatability of the problem - whether it is easy to repeat or happens randomly
  • steps to repeat - what you think caused the problem, ideally these steps should be repeated until they are as simple as possible and still cause the problem
  • desired outcome of the steps - that is, what you WANT to have happen
  • actual outcome of your steps - this is the essence of your problem

Compare these two bug reports:

MY PAGES ARE BLANK!!! I AM ABOUT TO DELETE DRUPAL FROM MY SYSTEM!!!

and

Repeatable: Always
Steps to repeat:
1. Download Module Foo
2. Uncompress foo-4.7.0-tar.gz into modules folder
3. Visit admin/modules page in site

Expected Results:
User sees the modules page and can enable the module Foo

Actual Results:
Page is completely blank.  Checking in the Apache Error Log showed this error:

Fatal error: Allowed memory size of 8388608 bytes exhausted (tried to allocate 418591 bytes) in /path/to/drupal/modules/foo/foo.module on line 42

The first bug report is relatively useless because it forces the developer to waste their time asking questions and guessing at the possible problem. The second one communicates the problem precisely and concisely. The user has described a specific set of steps that they took, the have stated that it is repeatable in their tests, and in addition to the desired and actual results they provided an exact error message from their system. This makes the developer's job relatively easy to try and find the problem.

HOWTO: Submit core issues

Thanks, saw your message, however I could not find where to submit an issue for the core 'Drupal' Project There is no Project in the global navigation, under Downloads, the Tile of the page is Projects, but the core project is not there, nor the core themes.

I had difficulty with it too, in the beginning. Here are the instructions:

  1. In the right menu, select 'Create Content'. Then Select 'Issue. You get the 'Submit issue' screen.
  2. Fill the project field. Examples - If you are trying to submit usability issues for the garland theme, select 'Drupal' (the second item under the 'Drupal Project' category) and click 'Next'. If you are trying to submit general usability issues which are not module specific, select the 'User Experience' project under the 'Drupal Project' category. You get the second issue submission screen.
  3. If you selected 'Drupal', you should now select the component to which the usability issue relates. Select 'Garland Theme' (it's in the bottom of the list) and try to fill as much details as possible about the issue, things which will help people visualize the problem. Add a link to a flickr picture of the usability issue, or record it as an AVI file with the free camstudio and upload it to a video sharing site, then give a link. This will highly improve the change of people understanding you. Or include the image as an attachment.
  4. After filling all details, press the submit bottom. Take care - you won't be able to later modify the text - only add new comments.
  5. Continue to update the issue to reflect new understanding you've got about the situation, and/or links to relevant information.

(adapted from http://drupal.org/node/118045)

Criteria for evaluating proposed changes

The following criteria are used by core developers in reviewing and approving
proposed changes:

  • The changes support and enhance Drupal project aims.
  • The proposed changes are current.Especially for new features, priority is usually given to development for the "HEAD" (the most recent development version of the code, also referred to as the CVS version) as opposed to released versions. There may have been significant changes since the last release, so developing for the CVS version means that
  • The proposed change doesn't raise any significant issues or risks.Specifically, issues that have been raised in the review process have been satisfactorily addressed.
  • The changes are well coded. At a minimum, this means coding in accordance with the Drupal coding standards. But it also means that the coding is intelligent and compact. Elegant solutions will have greater support than cumbersome ones that accomplish the same result.
  • There is demonstrated demand and support for the change. Demand is indicated by, e.g., comments on the drupal.org issues system or comments in forums or the drupal-dev email list.
  • The change will be used by a significant portion of the installed Drupal base as opposed being relevant only to a small subset of Drupal users.
  • The benefits of the change justifies additional code and resource demands. Every addition to the code base increases the quantity of code that must be actively maintained (e.g., updated to reflect new design changes or documentation approaches). Also, added code increases the overall Drupal footprint through, e.g., added procedure calls or database queries. Benefits of a change must outweigh these costs.

Effectively raising money to work on improvements to Drupal (reverse bounty)

So, you have a great idea for Drupal but can't take any time away from your "day job" to work on it. Fear not! This page will focus on some effective tools to raise money from the Drupal community to allow you to work on your beloved Drupal improvement.

Post a reverse bounty

A reverse bounty is an idea and feature description of something that a developer actually wants to work on, along with the money required to complete the task. The developer knows that it can be done, knows what the platform can do, and has the skills to actually implement it. The money allows them to dedicate time to actually work on it.

To learn more about the concept, take a look at Boris Mann's blog post on reverse bounties.

Post your idea in the paid Drupal services forum, and see if you can raise some interest first.

Show me the money!

Once you have an idea, you also need to quickly and effectively raise money to work on it. There are many ways a developer can raise money.

An example of a ChipIn widget.

ChipIn
I'm going to focus on my favorite, ChipIn. With ChipIn, you can create a donation widget where people can easily see what you're raising money for, how much you need, how much has been donated, who's donated, and when you need it by (see the screen shot to the right). They take a service fee, but it's comparable to what PayPal charges for most accounts.
Donorge
Drupal.org currently accepts donations through Donorge which has no donation fee. The motivation behind the open development of Donorge is to help support and increase the effect of donations made towards interests, needs, ideas and organization, either localized or connected around the world.
PayPal
PayPal is still a solid way to accept money, and although it doesn't give you the sweet widget data like ChipIn or have 0% transaction fees like Donorge, it's familiar territory for any scardy-cats.

Complete the work

With reverse bounties, most of the time the developer gets paid in full (or a deposit of 50%) before doing the work. As the developer, you have to be trust-worthy and complete the work in a reasonable amount of time.

Feature suggestions

How many times you have dreamed "Gee...I wish Drupal could do that" or "I like the xxx feature, but it should work better". If you want to improve Drupal, send us you wishes as a feature suggestions. Your suggestions play an essential role in making Drupal more usable and feature-rich.

The core features provided by Drupal are listed on the features page. You can submit a feature request by creating a new issue connected to the component the feature is related to. Please note that there is a Drupal contributed module named 'Features' which is used on the feature page mentioned above. Every module has a feature request subcategory, and thus the 'Feature' module is not the appropriate place to submit feature requests. To properly file a feature request, first choose the project it is related to and then after hitting preview set the other related options. You will be able to categorize the issue as a feature request with the Issue Information / Category dropdown.

Priority levels of Issues (Bugs and Features)

These are bugs that hold back a release

Critical
When a bug breaks all core or renders a popular function unusable. Possible examples: sessions, bootstrap one of the form elements or the ability to create a new node. These are to be fixed immediately because Drupal HEAD is not usable at all.

These are bugs that do not hold a release:

Normal bugs
Just bugs, we could even release with these. Just one functionality. Example: the category filter not working on node admin screen.
Minor bugs
Cosmetic issues, notices etc. Often also referred to as 'tasks' or features.

The revision process

Changes to the Drupal core are usually made after consideration, planning, and consultation.  They are also made on a priority basis--fixes come before additions, and changes for which there is a high demand come before proposals that have gone relatively unnoticed.  Any potential change has to be considered not only on its own merits but in relation to the aims and principles of the project as a whole.

The particular stages that a new feature goes through vary, but a typical cycle for a significant change might include:

  • General discussion of the idea, for example through a posting in a drupal.org forum.  This can be a chance to gauge support and interest, scope the issue, and get some
    direction and suggestions on approaches to take.  If you're considering substantive changes, starting out at the discussion level - rather than jumping straight into code changes - can save you a lot of time. 
  • Posting an issue through the drupal.org project system.
  • Discussion raising issues on the proposed direction or solution, which may include a real-time meeting through IRC. 
    Individual Drupal community members may vote for (+1) or against (-1) the change.  While informal, this voting system can help quantify support.
  • Producing a patch with specific proposed code changes.
  • Review of the changes and further discussion.
  • Revisions to address issues.
  • Possible application of the patch.

The process of discussion and revision might be repeated several times to encompass diverse input.  At any point in the process, the proposal might be:

  • Shelved as impractical or inappropriate.
  • Put off until other logically prior decisions are made.
  • Rolled into another related initiative.
  • Superceded by another change.

If you submit suggestions that don't end up being adopted, please don't be discouraged!  It doesn't mean that your ideas weren't good--just that they didn't end up finding a place.  The discussion itself may have beneficial outcomes.  It's all part of collaboratively building a quality open source project.

Maintaining a project on drupal.org

Each drupal.org project (a contributed theme, module or translation) needs to be maintained in the contributions repository. If you are not using the drupal.org infrastructure, you cannot setup a project page on drupal.org nor can you offer your module for download at drupal.org. Please note that all code which is commited into the Drupal CVS repository must be covered under the terms of the GNU General Public License.

Before creating a project page on drupal.org, you must apply for a CVS account. An administrator regularly reviews these requests and usually responds within one week. If you have included enough information and your proposed project does not duplicate existing work, your request will most likely be approved (via email). Once this happens, you will be able to use the cvs login command with your cvs user name. This will allow you to add a new directory to the CVS repository and commit your files. Please read the Drupal CVS handbook for more information about how to use CVS at drupal.org.

To get your project listed on drupal.org after it has been committed to CVS, fill in the form at http://drupal.org/node/add/project_project/.

  • Make sure that the 'Short project name' matches the directory name in the CVS repository. For example, the contributions/modules/my_module module has the short name my_module.
  • Fill in the correct value for the CVS directory field to match the path in the repository. In this case, you should include everything after the contributions part of the directory name (for example /modules/my_module/).
  • You should enable the issue tracker for your project to allow people will be able to file bugs against your project, add tasks, or request new features.
  • Please note that you must create a project node before you add any CVS tags or branches to your contribution, or you will run into errors when you try to make releases.

Once you submit the project page, it will be visible on drupal.org and people will immediately be able to create issues. You can use the My projects link in the main navigation menu to view any issues that have been submitted for your project(s).

In order for people to download your project, one or more "releases" will need to be created. Learn more about how to create releases at the Managing releases section of the CVS handbook pages.

Controlling CVS access

As the owner of a project, you will have full CVS access to a directory in the contributions repository. This directory holds all the files belonging to a specific contribution. If there is a team of multiple developers working on the same project, you can grant CVS access to other users and give them the ability to to commit and tag files in your project's directory. You do this by using the CVS access tab on your project's home page.

For example, if you are the owner of the event module, which lives at http://drupal.org/node/3238, then when you view this page you will see a new tab called CVS access, which can be found at http://drupal.org/node/3238/cvs-access. (Note: this link will not work unless you really are the maintainer of the event module, you'll have to view one of your projects to see the tab for yourself).

The CVS access tab allows you to grant other users CVS access to your project. There is a text field that will auto-complete with user names from drupal.org, to help you input a valid user. The form will verify that the user you select has an account on drupal.org and that the user has a valid CVS account. If your selection is valid, the user will be added to the table of users with CVS access on the page, and will be granted permission to commit and tag files in your project's directory.

Once you have granted access to a user, you can revoke the access by clicking the delete link next to their user name in the table of users with CVS access.

Any file included in your project that ends in .po or .pot will bypass this access control system. This way, module translators will be able to contribute translations without any additional effort or coordination with the project owner.

HOWTO: Checkout a drupal module from Drupal CVS

Checking out Drupal Modules and moving on with the current revision may be needed for developers and maintainers of drupal. But it took me time to figure out the main repo and the way to checkout from CVS. So, iam documenting here to make it helpful for whoever facing the same issue.

http://cvs.drupal.org/viewcvs/drupal/

If you want to see revisions under particular tag, give it like

http://cvs.drupal.org/viewcvs/drupal/?only_with_tag=DRUPAL-5--2

To checkout drupal, use

cvs -d ":pserver:anonymous:anonymous@cvs.drupal.org:/cvs/drupal" checkout -r HEAD drupal

or

cvs -d ":pserver:anonymous:anonymous@cvs.drupal.org:/cvs/drupal" checkout -r <tag-name> drupal

To checkout drupal modules, use

cvs -d ":pserver:anonymous:anonymous@cvs.drupal.org:/cvs/drupal" checkout -r HEAD contributions/modules/<module-name>

for example,
cvs -d ":pserver:anonymous:anonymous@cvs.drupal.org:/cvs/drupal" checkout -r HEAD contributions/modules/provisionator

Orphaned projects

If you are no longer capable of maintaining your project, please add a note to your project page and ask in the forums whether someone is willing to take over maintenance. The development mailing list is another good place to ask for volunteers. Proper communication is key so make sure to mark your project as orphaned. If you found a new maintainer or if you are willing to maintain an orphaned project, you should submit a task to the Drupal.org webmasters issue queue to request an ownership transfer (there's even an issue component called "Project ownership" you should use when submitting the task).

Tips for contributing to the core

The following tips might improve the chances of your contributions being accepted. Supplying patches is how to make changes to core or contributed code.

  • Start small. Review other patches and offer constructive suggestions and improvements. Tackle a few small bugs from the issue queue. Prove yourself. Before you wade in with a substantial change, develop a profile as a dependable, collaborative contributor.
  • Take a step back and objectively evaluate whether the changes are appropriate for the Drupal core. Ask yourself:
    • Is the feature already implemented? Search the forums and issue tracker.
    • Could the feature be implemented as a contributed module rather than a patch to the core?
    • Will the change benefit a substantial portion of the Drupal install base?
    • Is the change sufficiently general for others to build upon cleanly?
  • Be explanatory, provide descriptions and illustrations, make a good case. Don't count on others downloading, installing, and testing your changes. Rather, show them in a nutshell what your changes would mean. Anticipate and address questions or concerns. If appropriate, provide screenshots.
  • Be collaborative. Be friendly and respectful. Acknowledge the effort others put in.
  • Be open to suggestions and to other ways of accomplishing what you're aiming for.
  • Be persistent. If you don't get any response right away, don't necessarily give up. If you're still convinced your idea has merit, find another way to present it. Request another developer - ideally, one familiar with your work - to take the time to review your issue.
  • Respond, in a timely way, to suggestions, requests, or issues raised. Revise your work accordingly.
  • If some time has gone by, update your changes to work with the current CVS version.

List of maintainers

This comes from MAINTAINERS.txt, and may not be completely up to date. It roughly lists what users in the community maintain core Drupal modules. See Drupal core for more information on what this means.

BOOTSTRAP
Moshe Weitzman

BLOG API
James Walker

DISTRIBUTED AUTHENTICATION MODULES
Moshe Weitzman

DOCUMENTATION COORDINATOR
Charlie Lowe

FILTER SYSTEM
Steven Wittens

FORM SYSTEM
Károly Négyesi

LOCALE MODULE
Gábor Hojtsy

MENU SYSTEM
Richard Archer

TABLESORT API
Moshe Weitzman

PATH MODULE
Matt Westgate

POSTGRESQL PORT
Piotr Krukowiecki

SECURITY COORDINATOR
Károly Négyesi

STATISTICS MODULE
Jeremy Andrews

SEARCH
Steven Wittens

XML-RPC SERVER/CLIENT
Károly Négyesi

DEBIAN PACKAGE
Hilko Bengen

TRANSLATIONS COORDINATOR
Gerhard Killesreiter

THE REST:
Dries Buytaert

Mailing lists

Support

A list for support questions.

view archive . search archive . mailman page

Development

A list for Drupal developers.

view archive . search archive . mailman page

Themes

A list for Drupal theme developers/designers.

view archive . search archive . mailman page

Documentation

A list for documentation contributors.

view archive . search archive . mailman page

Translations

A list for Drupal UI translators.

view archive . search archive . mailman page

Consulting

A mailing list for Drupal consultants and Drupal service/hosting providers.

view archive . search archive . mailman page

CVS commits

A list with all CVS commit messages.

view archive . search archive . mailman page

CVS applications

A list of all applications for an account in the Drupal contributions CVS repository.

view archive . search archive . mailman page

Webmasters

A list for drupal.org webmasters (e.g. settings and content on the drupal.org website, user management, removing spam, etc.).

view archive . search archive . mailman page

Infrastructure

A list for drupal.org infrastructure maintainers (e.g. drupal.org hardware and server configuration, the CVS repository, mailing lists, etc).

view archive . search archive . mailman page

DrupalCON

A list for the organization of Drupal conferences and events.

view archive . search archive . mailman page

Subscribe

Mailing of project issues

In addition to the various mailing lists you can subscribe to, you can subscribe to project issue updates for any contributed module, theme, or translation. You can either subscribe to all issues for a given project, or only get emails for issues you have participated in (either submitted or posted a follow-up replly to).

All issues for certain projects (for example, the webmasters or infrastructure projects) are emailed to a corresponding mailing list.

Coding standards

Drupal Coding Standards

Note: The Drupal Coding Standards applies to code that is to become a part of Drupal. This document is based on the PEAR Coding standards.

Indenting

Use an indent of 2 spaces, with no tabs.

Control Structures

These include if, for, while, switch, etc. Here is an example if statement, since it is the most complicated of them:

if (condition1 || condition2) {
  action1;
}
elseif (condition3 && condition4) {
  action2;
}
else {
  defaultaction;
}

Control statements should have one space between the control keyword and opening parenthesis, to distinguish them from function calls.

You are strongly encouraged to always use curly braces even in situations where they are technically optional. Having them increases readability and decreases the likelihood of logic errors being introduced when new lines are added.

For switch statements:

switch (condition) {
  case 1:
    action1;
    break;

  case 2:
    action2;
    break;

  default:
    defaultaction;
    break;
}

Function Calls

Functions should be called with no spaces between the function name, the opening parenthesis, and the first parameter; spaces between commas and each parameter, and no space between the last parameter, the closing parenthesis, and the semicolon. Here's an example:

$var = foo($bar, $baz, $quux);

As displayed above, there should be one space on either side of an equals sign used to assign the return value of a function to a variable. In the case of a block of related assignments, more space may be inserted to promote readability:

$short         = foo($bar);
$long_variable = foo($baz);

Function Declarations

function funstuff_system($field) {
  $system["description"] = t("This module inserts funny text into posts randomly.");
  return $system[$field];
}

Arguments with default values go at the end of the argument list. Always attempt to return a meaningful value from a function if one is appropriate.

Arrays

Arrays should be formatted with a space separating each element and assignment operator, if applicable:

$some_array = array('hello', 'world', 'foo' => 'bar');

Note that if the line spans longer than 80 characters (often the case with form and menu declarations), each element should be broken into its own line, and indented one level:

$form['title'] = array(
  '#type' => 'textfield',
  '#title' => t('Title'),
  '#size' => 60,
  '#maxlength' => 128,
  '#description' => t('The title of your node.'),
);

Note the comma at the end of the last array element--this is not a typo! It helps prevent parsing errors if another element is placed at the end of the list later.

Comments

Inline documentation for classes should follow the Doxygen convention. More information about Doxygen can be found here:

Note that Drupal uses the following docblock syntax:

/**
 * Comments.
 */

And all Doxygen commands should be prefixed with a @ instead of a /.

Non-documentation comments are strongly encouraged. A general rule of thumb is that if you look at a section of code and think "Wow, I don't want to try and describe that", you need to comment it before you forget how it works.

C style comments (/* */) and standard C++ comments (//) are both fine. Use of Perl/shell style comments (#) is discouraged.

Including Code

Anywhere you are unconditionally including a class file, use require_once(). Anywhere you are conditionally including a class file (for example, factory methods), use include_once(). Either of these will ensure that class files are included only once. They share the same file list, so you don't need to worry about mixing them - a file included with require_once() will not be included again by include_once().

Note: include_once() and require_once() are statements, not functions. You don't need parentheses around the filename to be included.

PHP Code Tags

Always use <?php ?> to delimit PHP code, not the <? ?> shorthand. This is required for Drupal compliance and is also the most portable way to include PHP code on differing operating systems and setups.

Note that the final ?> should be omitted from all code files--modules, includes, etc. The closing delimiter is optional, and removing it helps prevent unwanted white space at the end of files which can cause problems elsewhere in the system. More information is available from the PHP Code tags portion of the handbook.

Header Comment Blocks

All source code files in the core Drupal distribution should contain the following comment block as the header:

<?php
// $Id$

This tag will be expanded by the CVS to contain useful information

<?php
// $Id: CODING_STANDARDS.html,v 1.7 2005/11/06 02:03:52 webchick Exp $

Using CVS

Include the Id CVS keyword in each file. As each file is edited, add this tag if it's not yet present (or replace existing forms such as "Last Modified:", etc.).

The rest of this section assumes that you have basic knowledge about CVS tags and branches.

CVS tags are used to label which revisions of the files in your package belong to a given release. Below is a list of the required CVS tags:

DRUPAL-X-Y
(required) Used for tagging a release. If you don't use it, there's no way to go back and retrieve your package from the CVS server in the state it was in at the time of the release.

Example URLs

Use "example.com" for all example URLs, per RFC 2606.

Naming Conventions

Functions and Methods

Functions and methods should be named using lower caps and words should be separated with an underscore. Functions should in addition have the grouping/module name as a prefix, to avoid name collisions between modules.

Private class members (meaning class members that are intended to be used only from within the same class in which they are declared; PHP 4 does not support truly-enforceable private namespaces) are preceded by a single underscore. For example:

_node_get()

$this->_status

Constants

Constants should always be all-uppercase, with underscores to separate words. Prefix constant names with the uppercased name of the module they are a part of.

Global Variables

If you need to define global variables, their name should start with a single underscore followed by the module/theme name and another underscore.

Filenames

All documentation files should have the filename extension ".txt" to make viewing them on Windows systems easier. Also, the filenames for such files should be all-caps (e.g. README.txt instead of readme.txt) while the extension itself is all-lowercase (i.e. txt instead of TXT).

Examples: README.txt, INSTALL.txt, TODO.txt, CHANGELOG.txt etc.

Doxygen formatting conventions

Doxygen is a documentation generation system. The documentation is extracted directly from the sources, which makes it much easier to keep the documentation consistent with the source code.

There is an excellent manual at the Doxygen site. The following notes pertain to the Drupal implementation of Doxygen.

General documentation syntax

To document a block of code, the syntax we use is:

/**
* Documentation here.
*/

Doxygen will parse any comments located in such a block. Our style is to use as few Doxygen-specific commands as possible, so as to keep the source legible. Any mentions of functions or file names within the documentation will automatically link to the referenced code, so typically no markup need be introduced to produce links.

Documenting files

It is good practice to provide a comment describing what a file does at the start of it. For example:

<?php
// $Id: theme.inc,v 1.202 2004/07/08 16:08:21 dries Exp $

/**
* @file
* The theme system, which controls the output of Drupal.
*
* The theme system allows for nearly all output of the Drupal system to be
* customized by user themes.
*/

The line immediately following the @file directive is a short description that will be shown in the list of all files in the generated documentation. If the line begins with a verb, that verb should be in present tense, e.g., "Handles file uploads." Further description may follow after a blank line.

To add CVS ID-Tags to your file, add a // $Id$ to your file. CVS will automatically expand it to the format shown above. In the future, you don't have to care about that as CVS will update these information automatically.

Documenting functions

All functions that may be called by other files should be documented; private functions optionally may be documented as well. A function documentation block should immediately precede the declaration of the function itself, like so:

/**
* Verify the syntax of the given e-mail address.
*
* Empty e-mail addresses are allowed. See RFC 2822 for details.
*
* @param $mail
*   A string containing an email address.
* @return
*   TRUE if the address is in a valid format.
*/
function valid_email_address($mail) {

The first line of the block should contain a brief description of what the function does, beginning with a verb in the form "Do such and such" (rather than "Does such and such"). A longer description with usage notes may follow after a blank line. Each parameter should be listed with a @param directive, with a description indented on the following line. After all the parameters, a @return directive should be used to document the return value if there is one. There is no blank line between the @param and @return directives. Functions that are easily described in one line may omit these directives, as follows:

/**
* Convert an associative array to an anonymous object.
*/
function array2object($array) {

The parameters and return value must be described within this one-line description in this case.

Documenting hook implementations

Many modules consist largely of hook implementations. If the implementation is rather standard and does not require more explanation than the hook reference provides, a shorthand documentation form may be used:

/**
* Implementation of hook_help().
*/
function blog_help($section) {

This generates a link to the hook reference, reminds the developer that this is a hook implementation, and avoids having to document parameters and return values that are the same for every implementation of the hook.

Documenting themeable functions

In order to provide a quick reference for theme developers, we tag all themeable functions so that Doxygen can group them on one page. To do this, add a grouping instruction to the documentation of all such functions:

/**
* Format a query pager.
*
* ...
* @ingroup themeable
*/
function theme_pager($tags = array(), $limit = 10, $element = 0, $attributes = array()) {
  ...
}

The same pattern can be used for other functions scattered across multiple files that need to be grouped on a single page.

Configuring Eclipse

This describes how to configure Eclipse to play nicely with Drupal.

For PHPeclipse - PHP editing

We need to ensure that tab/indent inserts two spaces, and also that .inc, .module, .engine, .theme and .install files are recognised as PHP files.

Make the following changes under Window -> Preferences

  1. Expand the left-hand menu to General -> Content Types
    Under "Content types" on the right, click Text -> PHP Source File
    Add the *.engine, *.theme, *.install, *.inc, and *.module file types
  2. In the left-hand menu click on PHPeclipse Web Development -> PHP
    In the Typing tab, make sure the 'Insert Spaces for Tab' setting is checked
    In the Appearance tab, it is reccommended that you leave the 'Displayed tab width' at 4, so it is easier to spot if any (actual) tabs have snuck in
  3. In the left-hand menu click on PHPeclipse Web Development -> PHP -> Formatter
    In the Style tab, enter 2 for 'Number of spaces representing a tab'
    'Compact Assignment' and 'Indentation is represented by a tab' should both be unchecked

For Eclipse Web Tools - CSS, JS, XML and (X)HTML editing

Window -> Preferences -> Web and XML -> CSS Files -> CSS Source
Select 'Indent using spaces'
Set 'Intentation size' to 2

Window -> Preferences -> Web and XML -> Javascript Files -> Javascript Source
Select 'Indent using spaces'
Set 'Intentation size' to 2

Window -> Preferences -> Web and XML -> HTML Files -> HTML Source
Select 'Indent using spaces'
Set 'Intentation size' to 2

Window -> Preferences -> Web and XML -> XML Files -> XML Source
Select 'Indent using spaces'
Set 'Intentation size' to 2

If you use XTemplate:
Window -> Preferences -> General -> Content Types -> Text -> HTML
Add the *.xtmpl file type

Configuring Emacs

This short snippet will extend the php-mode in Emacs to follow drupals coding style. Add this to your $HOME/.emacs:

(defun drupal-mode ()
  (interactive)
  (php-mode)
  (setq c-basic-offset 2)
  (setq indent-tabs-mode nil)
  (setq fill-column 78)
  (c-set-offset 'case-label 2)
  (c-set-offset 'arglist-close 0))

(add-to-list 'auto-mode-alist '("/drupal.*\\.\\(php\\|module\\|inc\\)$" . drupal-mode))

This will automatically set you in drupal-mode if you load a .php, .module or .inc file from beneath a drupal* directory. You may also manually select drupal mode by hitting M-x drupal-mode.

Configuring vim

Indentation

The following commands will indent your code the right amount, using spaces rather than tabs and automatically indent after you start.

set expandtab
set tabstop=2
set shiftwidth=2
set autoindent
set smartindent

Syntax highlighting

If you enjoy syntax highlighting, it is may be worth remembering that many of Drupal's php files are *.module or *.inc, among others.

Using these settings only with Drupal

  • Copy your .vimrc to .vimrc-drupal
  • Append these settings to the end
  • Run vim -u ~/.vimrc-drupal

To make this easier (using bash on Linux), you could create an alias by typing:

alias vid="vim -u ~/.vimrc-drupal"

This allows you to just use the vid command instead of vi when you want to edit a Drupal file.

Vim seems to syntax highlight *.inc files properly by default but doesn't kow that *.module is PHP content. For *.modules use this snippet in .vimrc:

if has("autocmd")
  " Drupal *.module files.
  augroup module
    autocmd BufRead                     *.module set filetype=php
  augroup END
endif

Guidelines for better performing code

This article is a stub, please help expand and correct this

String Comparison

Using empty() is reported to be about 20% faster than comparison with '' or "" (zero-length strings).
So

<?php
if ($var == "") {
}
?>

Should not be used, instead use
<?php
if (empty($var)) {
}
?>

Indenting

Use an indent of 2 spaces, with no tabs. No trailing spaces.

PHP Code tags

Always use <?php ?> to delimit PHP code, not the <? ?> shorthand. This is required for Drupal compliance and is also the most portable way to include PHP code on differing operating systems and setups.

Note that as of Drupal 4.7, the ?> at the end of code files (modules, includes, etc.) is purposely omitted. The full discussion that led to this decision is available from the no ?> needed at the end of modules discussion on the drupal-devel mailing list, but can be summarized as:

  • Removing it eliminates the possibility for unwanted whitespace at the end of files which can cause "header already sent" errors, XHTML/XML validation issues, and other problems.
  • The closing delimiter at the end of a file is optional.
  • PHP.net itself removes the closing delimiter from the end of its files (example: prepend.inc), so this can be seen as a "best practice."

SQL naming conventions

http://drupal.org/node/2497/

-->
  • Don't use (ANSI) SQL / MySQL / PostgreSQL / MS SQL Server / ... Reserved Words for column and/or table names. Even if this may work with your (MySQL) installation, it may not with others or with other databases. Some references:

    Some commonly misused keywords: TIMESTAMP, TYPE, TYPES, MODULE, DATA, DATE, TIME, ...
    See also [bug] SQL Reserved Words.

  • Capitalization, Indentation
    • UPPERCASE reserved words
    • lowercase (or Capitalize) table names
    • lowercase column names

    Example:

      SELECT r.rid, p.perm
      FROM {role} r
        LEFT JOIN {permission} p ON r.rid = p.rid   -- may be on one line with prev.
      ORDER BY name
     
  • Naming
    • Use plural or collective nouns for table names since they are sets and not scalar values. (Others prefer that table names to match field name, so prefer singular table names. Drupal uses both: blocks, filters, users; but book, poll, role.)
    • Name every constraint (primary, foreign, unique keys) yourself. Otherwise you'll see funny-looking system-generated names in error messages. This happened with the moderation_roles table which initially defined a key without explicite name as KEY (mid). This got mysqldump'ed as KEY mid (mid) which resulted in a syntax error as mid() is a mysql function (see [bug] mysql --ansi cannot import install database).
    • Index names should begin with the name of the table they depend on, eg. INDEX users_sid_idx.

References:

List of SQL Reserved Words

The list below represents a combination of the following sources of SQL reserved words:

There are undoubtedly more sources that we should add to this list, but this makes a very good starting point.

Reserved Words
  1. A

  2. ABORT

  3. ABS

  4. ABSOLUTE

  5. ACCESS

  6. ACTION

  7. ADA

  8. ADD

  9. ADMIN

  10. AFTER

  11. AGGREGATE

  12. ALIAS

  13. ALL

  14. ALLOCATE

  15. ALSO

  16. ALTER

  17. ALWAYS

  18. ANALYSE

  19. ANALYZE

  20. AND

  21. ANY

  22. ARE

  23. ARRAY

  24. AS

  25. ASC

  26. ASENSITIVE

  27. ASSERTION

  28. ASSIGNMENT

  29. ASYMMETRIC

  30. AT

  31. ATOMIC

  32. ATTRIBUTE

  33. ATTRIBUTES

  34. AUDIT

  35. AUTHORIZATION

  36. AUTO_INCREMENT

  37. AVG

  38. AVG_ROW_LENGTH

  39. BACKUP

  40. BACKWARD

  41. BEFORE

  42. BEGIN

  43. BERNOULLI

  44. BETWEEN

  45. BIGINT

  46. BINARY

  47. BIT

  48. BIT_LENGTH

  49. BITVAR

  50. BLOB

  51. BOOL

  52. BOOLEAN

  53. BOTH

  54. BREADTH

  55. BREAK

  56. BROWSE

  57. BULK

  58. BY

  59. C

  60. CACHE

  61. CALL

  62. CALLED

  63. CARDINALITY

  64. CASCADE

  65. CASCADED

  66. CASE

  67. CAST

  68. CATALOG

  69. CATALOG_NAME

  70. CEIL

  71. CEILING

  72. CHAIN

  73. CHANGE

  74. CHAR

  75. CHAR_LENGTH

  76. CHARACTER

  77. CHARACTER_LENGTH

  78. CHARACTER_SET_CATALOG

  79. CHARACTER_SET_NAME

  80. CHARACTER_SET_SCHEMA

  81. CHARACTERISTICS

  82. CHARACTERS

  83. CHECK

  84. CHECKED

  85. CHECKPOINT

  86. CHECKSUM

  87. CLASS

  88. CLASS_ORIGIN

  89. CLOB

  90. CLOSE

  91. CLUSTER

  92. CLUSTERED

  93. COALESCE

  94. COBOL

  95. COLLATE

  96. COLLATION

  97. COLLATION_CATALOG

  98. COLLATION_NAME

  99. COLLATION_SCHEMA

  100. COLLECT

  101. COLUMN

  102. COLUMN_NAME

  103. COLUMNS

  104. COMMAND_FUNCTION

  105. COMMAND_FUNCTION_CODE

  106. COMMENT

  107. COMMIT

  108. COMMITTED

  109. COMPLETION

  110. COMPRESS

  111. COMPUTE

  112. CONDITION

  113. CONDITION_NUMBER

  114. CONNECT

  115. CONNECTION

  116. CONNECTION_NAME

  117. CONSTRAINT

  118. CONSTRAINT_CATALOG

  119. CONSTRAINT_NAME

  120. CONSTRAINT_SCHEMA

  121. CONSTRAINTS

  122. CONSTRUCTOR

  123. CONTAINS

  124. CONTAINSTABLE

  125. CONTINUE

  126. CONVERSION

  127. CONVERT

  128. COPY

  129. CORR

  130. CORRESPONDING

  131. COUNT

  132. COVAR_POP

  133. COVAR_SAMP

  134. CREATE

  135. CREATEDB

  136. CREATEROLE

  137. CREATEUSER

  138. CROSS

  139. CSV

  140. CUBE

  141. CUME_DIST

  142. CURRENT

  143. CURRENT_DATE

  144. CURRENT_DEFAULT_TRANSFORM_GROUP

  145. CURRENT_PATH

  146. CURRENT_ROLE

  147. CURRENT_TIME

  148. CURRENT_TIMESTAMP

  149. CURRENT_TRANSFORM_GROUP_FOR_TYPE

  150. CURRENT_USER

  151. CURSOR

  152. CURSOR_NAME

  153. CYCLE

  154. DATA

  155. DATABASE

  156. DATABASES

  157. DATE

  158. DATETIME

  159. DATETIME_INTERVAL_CODE

  160. DATETIME_INTERVAL_PRECISION

  161. DAY

  162. DAY_HOUR

  163. DAY_MICROSECOND

  164. DAY_MINUTE

  165. DAY_SECOND

  166. DAYOFMONTH

  167. DAYOFWEEK

  168. DAYOFYEAR

  169. DBCC

  170. DEALLOCATE

  171. DEC

  172. DECIMAL

  173. DECLARE

  174. DEFAULT

  175. DEFAULTS

  176. DEFERRABLE

  177. DEFERRED

  178. DEFINED

  179. DEFINER

  180. DEGREE

  181. DELAY_KEY_WRITE

  182. DELAYED

  183. DELETE

  184. DELIMITER

  185. DELIMITERS

  186. DENSE_RANK

  187. DENY

  188. DEPTH

  189. DEREF

  190. DERIVED

  191. DESC

  192. DESCRIBE

  193. DESCRIPTOR

  194. DESTROY

  195. DESTRUCTOR

  196. DETERMINISTIC

  197. DIAGNOSTICS

  198. DICTIONARY

  199. DISABLE

  200. DISCONNECT

  201. DISK

  202. DISPATCH

  203. DISTINCT

  204. DISTINCTROW

  205. DISTRIBUTED

  206. DIV

  207. DO

  208. DOMAIN

  209. DOUBLE

  210. DROP

  211. DUAL

  212. DUMMY

  213. DUMP

  214. DYNAMIC

  215. DYNAMIC_FUNCTION

  216. DYNAMIC_FUNCTION_CODE

  217. EACH

  218. ELEMENT

  219. ELSE

  220. ELSEIF

  221. ENABLE

  222. ENCLOSED

  223. ENCODING

  224. ENCRYPTED

  225. END

  226. END-EXEC

  227. ENUM

  228. EQUALS

  229. ERRLVL

  230. ESCAPE

  231. ESCAPED

  232. EVERY

  233. EXCEPT

  234. EXCEPTION

  235. EXCLUDE

  236. EXCLUDING

  237. EXCLUSIVE

  238. EXEC

  239. EXECUTE

  240. EXISTING

  241. EXISTS

  242. EXIT

  243. EXP

  244. EXPLAIN

  245. EXTERNAL

  246. EXTRACT

  247. FALSE

  248. FETCH

  249. FIELDS

  250. FILE

  251. FILLFACTOR

  252. FILTER

  253. FINAL

  254. FIRST

  255. FLOAT

  256. FLOAT4

  257. FLOAT8

  258. FLOOR

  259. FLUSH

  260. FOLLOWING

  261. FOR

  262. FORCE

  263. FOREIGN

  264. FORTRAN

  265. FORWARD

  266. FOUND

  267. FREE

  268. FREETEXT

  269. FREETEXTTABLE

  270. FREEZE

  271. FROM

  272. FULL

  273. FULLTEXT

  274. FUNCTION

  275. FUSION

  276. G

  277. GENERAL

  278. GENERATED

  279. GET

  280. GLOBAL

  281. GO