The first rule of coding for Drupal: never forget about the option to write your own code.
yelvington writes: “The first rule of coding for Drupal: We do not write code for Drupal.” I must say, that after years , I come to the exact opposite conclusion. Right now, I should be writing another webshop (instead I am writing a blog-post, but this article is not about procastrination :)).
I was one of the most outspoken for getting the first CCK, flexinode into core. Not that project itself, per sé, but the concept. I have been a firm believer of “don’t duplicate code”, as such I even introduced the rule in Drupal Join forces with others. I consider myself a moderate programmer (speaking some Perl, Bash, rather good Ruby, almost Fluent PHP and rusty C, C++ and even som Java; hardly a hardcore programmer), I am lazy and tend to be pragmatic (and most often disguise the former by calling it ‘pragmatic’ :)).
Why write yet another shop-system when you can pick from several e-commerce tools? Because face it: e-commerce is not ready. Übercart -no offence!- simply sucks, for extendability, usability and flexibility. But that was not the main reason, that was more technical. More on that later.
Views has a performance horror luring around the corner. It might not hit you, but often will — Views is not bad performant per sé, but it can be. CCK - well, exactly the same. And panels. Don’t get me started on that! If you sincerely hate your frontend developers, give them panels. I have seriously had a person resign from his job because of panels used int their project (panels 2 in his defence, 3 is an improvement). But I do use Views in most projects, together with -obviously- CCK and about 20 other modules.
Views, CCK, Panels are all great tools for the average quick project. Typically projects where the 80/20 rule is applied as: we build 80 and forget about the 20. And we all know the problem that features tries to solve: you create CCK fields, use these in (dependant!) views, and override that in -PHP- templates. The always returning staging-horror. AKA ‘simply repeat the creation on LIVE all over again’. But I do not want to go into more details on the technical downsides of these modules. However important, a far greater concern outshadows these by far.
The problem that made me switch 180° was the development for and in CCK, views, panels and all these high-level buildingbricks. To illustrate, let me give you some quit often repeating questions; try to build them with CCK, views and related modules:
- An event-listing: next upcoming item, whose end-date is not yet passed (event is not yet finished), grouped by day.
- An article with some fields extracted (live) from a webservice: content lives not in the local database, but is pulled over SOAP, REST or similar. E.g. the editor fills in the “trailer_id” and the trailer is pulled from a filmtrailer service.
- On Cron, fill certain nodes with data from a service or an XML-file.
- Validate a postal-code field against a city-field; a postal-code implies a certain city. (using, e.g. a local lookup-table or some provided library).
- People must provide either a telephone OR an emailfield.
- After submitting a node (say a classified ad) people are redirected to the next node form (say, to add photo’s), of wich parts are pre-filled and which is related to the first (in database or ORM speak: one classified has_many photo’s)
- A table, listing all profile-nodes, but where the fields Prefix, FirstName, middlename, SurName, Postfix are aggregated into one column, sortable by Surname.
Right? Off course, with the right combination of computed fields, custom template logic(!) and maybe some views and CCK addons it is possible. But far from easy.
Now, I developed each and every of above in custom modules. Let me summarise how I did that, and how many code it required.
- Eventlisting: Custom node, defined in an event.module, with a (really simple) date-field, and a (slightly less simple) database query, pushing that to a theme(‘table’). Done. Isolated code for this is less then 200 lines, one small module! The module became more complex, because we changed the model into “event has_many playdates” later. Now bearing less then 600 lines, still small.
- Extraced content from a webservice: Very small custom node, defined in movie.module, on hook_insert etc. insert the ID into a local joined table, hook_load request external source using the value from the table. Tiny module, without theme functions, less then 400 lines of PHP.
- Fill from an external resource: On cron, fill some custom module-defined nodes. Before we filled CCK-nodes, but the dynamic use of database (database layout changes when reconfiguring fields) made us decide to simply push all data to our custom joined table. Simple. Effective. Less then a thousand lines code, with most code on the XML parsing and validation.
- Telephone or mailfield: A custom node, joined table, with hook_validate checking existence of one of both fields and presenting user with a proper message. Less then 40 lines of PHP. 20 minutes development or so. Other fields on this custom node are added with CCK.
- A module with several custom nodes, extendable with CCK, but some fields are stored in the database (e.g. the abovementioned telephone/mail fields) module does redirecting, validating and pre-filling on several hooks provided by Drupal. One of the larger modules, still less then 1000 lines of PHP.
- Simple SQL pager-query, some PHP looping over the items and aggregating them at wish. Less then 50 lines of PHP. Less then an hour development.
I am not trying to look cool and say “look how fast and small I can develop”, nor do I want to thumb down CCK or views, or any of the other buidling blocks. I am trying to point out how an often forgotten, simple tool can aid. And that writing Views addons, CCK plugins and the likes requires far -FAR- more development, complexity. Will introduce a lot more (unhandled) edge cases (seen a module that does not handle multiple fields correct lately?). And offers hardly any benefit other then the -theoretically- better re-usability. Theoretically, because when being pragmatic, you can just as easy copy paste some code from an old project, then wrinting a perfectly flexible and generic solution.
To illustrate: we spent a month on addons for übercart, views and CCK: simgle-click-checkout, insert barcode in invoices, hacking the Übercart interface in templates, writing complex -dependant and relating- fields for CCK, and so on. The client was not very happy with the workflow, we were far less happy with the enormous amount of (dependant!) code for all the addons and overrides. Loosing all the benefits of re-using code. A complex form-alter introduces just the same amount of tight coupling as a fork would: you have to maintain your form-alter code on every change of the altered form, just as well. An amount of override and template code that extends the amount of re-used code, defeats the purpose of getting a quick start.
Rewriting the entire thing in my own modules took less then 3 weeks. And we are far futher then then 80% now, nearing 90. While the generic solution left us entirely stuck at 80%. Not being able to get out, with the only solution “convince the client that the last 20% is not very important”. Well it was, and right so. We killed a project wich required over 30 modules and 3000+ lines of template code to be replaced by two custom modules (4000+lines, so rather large) and no template logic.
As if a carpenter only uses his completely computerised drilling robot, automated sawing machines and super-hightech-glue-gun. When often a handsaw, nail and hammer will get to planks together in less then 5 minutes. A good carpenter might have all the hight-teck tools, but never forgets about the ease and speed of a hammer and a nail.
So, yes. Using Views and CCK helps you forward. And will get your to the 100% if your 100% is not that demanding. Say, in rapid prototyping; get up a CCK+views+panels version in a few hours, see if the general idea is good, throw it out and rerite it in your own code.
But when you’re requirements are slightly more specialised then a few simple modules, -developed in PHP-, are the quickest, cleanest and most pragmatic way. The only way that will make your client 100% happy. Especially when you are your own client!
edit we had over 3000 lines, not over 300 lines of template code.

Hey, I believe you’re
Hey,
I believe you’re right, as long as you are in a small team, with very good people that have strong self-discipline, and one overall architect that monitor the technical organization.
Have one of these things missing, and you will end with a maintenance nightmare.
I work for a big newspaper website with lots of customization and now almost 100,000 custom lines of codes (+100 custom modules), we are still using CCK, Views and others big drupal modules, and I am grateful to that.
Thanks to that, people that come and leave from the project are getting very quickly used to the code, and maintenance is quite easy. That was not the case on the previous version of the website when people began to shift away from the big modules, for the sake of speed.
But I will agree that on critical pieces for our business, when an existing module is clearly not designed the good way (and you have to be sure of it), it is much better to rewrite it for our purpose than twisting ourselves to make it work. We have done that for a couple of modules, ~5.
I believe that if you stay as close as possible to the main modules, maintenance will be much easier.
You are right about
You are right about maintainabilility, up to a certain point.
You see, modules on Drupal.org are just as (un)maintained as your own modules. With the one difference: you have no control over it.
Sure, you can select modules based on their maintainer, state and so on. But many project is badly maintained, chooses to rewrite the whole thing every year or so (views), or is simply full of bugs. Some are plain unstable (but released as stable) while others are never released as stable (but may be a lot more stable then the first).
Point is, in practice, maintaining 10+ modules on each project hardly adds more maintainance burden then pulling in 10+ random contrib modules.
Now, maintaining 10+ badly written, hacked up custom modules, that is a problem.
But so is pulling in 10+ badly written, hackud up contrib modules.
You should compare well written modules to well written modules. As you point out too, bytheway.
And compare badly written, badly maintained and ugly modules to your own hacked up, proof-of-concept-became-live-modules.
And seriously, there are a lot of badly written, poorly documented and simply leak-as-a-basket modules out there. We often don’t see that, because pulling in a module does not require you to open “the hood” and look under it.
This is not the NIS, but simply the fact that Drupal contributors are very different in background, goals and such.
Again, I stress: if you need 3000+ lines of template logic(!) to beat your views and CCK and forms in shape, you will probably be far better of with a 3000+ lines module. Even more so, because you will most probably never need that amount of logic in a module, as you would in a template. Even more so, because template logic(!) is always wrong. a Template should never bear logic.
Well the thing that you have
Well the thing that you have to note is that in some simple cases cck and views make it very fast to develop a website.
For more “custom” solutions, custom code is always the best option, because of the fact that a module can be so general until it gets too slow.
The one thing i would like to have is xml files or some sort for input types and maybe views like symphony-cms will have on 2.1 for it’s input types,
I did note that Views, CCK,
I did note that Views, CCK, Panels are all great tools for the average quick project. Typically projects where the 80/20 rule is applied as: we build 80 and forget about the 20.
XML files for input types, at least, that is how I intepret it, is not possible.
But what gets very close, is your custom module-defined node-type. Slightly more verbose then XML, or INI, but set in code: a fefw welldefined hooks and an .install file for the database scheme. The hookinsert will map fields to database-columns. The hookform builds the forms itself, and the hookvalidate validates them. Hookload will fetch the items from the database and prepare them for displaying. (M-model and C-controller). Then hook_view will create rendarable content for use in the theme (V-view).
So, not as abstract as XML, but about as verbose, and about the same amount of typing required.