Categories
Drupal Planet

Thumbnails by node id in Drupal

My problem:
I’d like to be able to automatically construct a URL along the lines of http://www.mydrupalsite.com/images/thumbs/node/1.jpg and get back a JPEG image that represents that node. Most of my nodes have a field_pictures imagefield that takes multiple images, and they also use imagecache to generate thumbnails. I just want to bridge the gap between node and primary photo – the first photo in the list is fine as the primary photo, I just would like to be able to load a thumbnail image for a node without knowing anything else about it. This probably isn’t an issue for a pure Drupal installation, but in my case, I don’t want to load a node JSON array over the network to the iPhone, have the iPhone parse out the name first picture (if it exists), and then construct a URL to the thumbnail.

I’ve searched through Drupal.org for a module that already did this, or perhaps another solution, and there isn’t one. I know I don’t need to replicate imagecache’s functionality – I’d like to build on top of imagecache actually, and use imagecache to generate the thumbnails.

My thought is to create a new module that hooks onto a custom URL, and then when it receives a request for a thumbnail from say, node 1, returns either the thumbnail from imagecache, or a default/blank 64×64 JPEG. The way the module would work, it would load the node and take a look at the first image in field_pictures. If there is no image, return the default.jpg. If there is an image in the cache, serve up the image from the cache. If there is no image in the cache, use imagecache to create one, and then serve it.

Next steps are to look into the imagecache module to see what I can hook into or take advantage of for functionality.

This will make displaying thumbnails for each node in my iPhone app much easier than trying to create custom views for each set of node references in my application and maintaining that.

Categories
Drupal Planet

Using Zen as a Base Theme for a new Drupal Theme

As part of the Drupal Theming Study Group, we’re taking a look at using the Drupal base theme Zen as the starting point for our themes. The Zen theme isn’t ready to go by itself – you will need to create your own theme and customize that to get a Drupal site up and running that looks halfway decent.

The first step to using Zen is to download Zen and install it in sites/all/themes. In this case, we’re using version 6.x-2.0, which is important as there is lots of documentation about Zen that is outdated because the theme was reorganized. This was pretty confusing when we got started. Using drush, the command is:

drush dl zen

We enabled zen from the /admin/build/themes Themes Administration Page. The zen theme does display your content, but it does not look pretty. Here is a screenshot of a Drupal installation running Zen:

We’ve got a long way to go before that looks good. To get started, we’re going to create a sub-theme based on Zen. Zen makes this very easy by supplying a complete ready-to-go subtheme in a folder called STARTERKIT. The directions to create the subtheme are in STARTERKIT/README.TXT, and should be followed in that order – they are pretty straightforward.

After you follow the directions in the README.TXT, you will have a new theme directory, but your theme will still look exactly like Zen. This is because you haven’t actually done anything to the visual layout,unless you chose to go with a fluid layout instead of a fixed layout (Step 3 of the README.TXT).

Zen’s CSS Files

The next step is to start editing your new theme’s CSS files. This is where we ran into problems with the Zen documentation, because it wasn’t clear which of the CSS files did what. So we started with the sub-theme’s INFO file, to see which CSS files were included, by default:

stylesheets[all][] = css/html-reset.css
stylesheets[all][] = css/wireframes.css
stylesheets[all][] = css/layout-fixed.css
stylesheets[all][] = css/page-backgrounds.css
stylesheets[all][] = css/tabs.css
stylesheets[all][] = css/messages.css
stylesheets[all][] = css/pages.css
stylesheets[all][] = css/block-editing.css
stylesheets[all][] = css/blocks.css
stylesheets[all][] = css/navigation.css
stylesheets[all][] = css/panels-styles.css
stylesheets[all][] = css/views-styles.css
stylesheets[all][] = css/nodes.css
stylesheets[all][] = css/comments.css
stylesheets[all][] = css/forms.css
stylesheets[all][] = css/fields.css
stylesheets[print][] = css/print.css

This is a pretty long and exhaustive list of CSS files. Starting from the beginning, we have

html-reset.css

This looks like it would be your “reset” CSS file that is quite popular in some circles, but in this case, the inline comments actually say that it’s for setting your default CSS properties instead. I suppose that if you were going to use Blueprint or 960 Grid System with Zen instead, you wouldn’t use this CSS file. In here, you will find:

  • default font settings for individual elements
  • margin, line-height, and font size for headings
  • margins for block-level elements
  • margins and paddings for list elements
  • settings for hyperlinks, in the correct order (link,visited,hover,focus,active)
  • table settings,abbreviations,images, horizontal rules and forms

If you need to change a site-wide default for these elements, do it here.

wireframes.css

Under Theme Development Settings for your subtheme, you can turn on wireframes for development/design purposes with the “Display borders around main layout elements” setting. You won’t need to edit this file.

layout-fixed.css and layout-liquid.css

With Zen, you can have a fixed layout or a fluid layout. Zen is a tableless design. Use layout-fixed.css to have a fixed width layout, or layout-liquid.css to have a fluid layout. In either case, you will edit this file to change the overall structure, positioning, and layout of your site – positions of divs, widths, heights, margins, borders, and padding.

Major elements of your Zen-based site are:

  • body
  • page-wrapper
  • page
  • header
  • search-box
  • main-wrapper
  • main
  • content
  • navigation
  • first sidebar
  • second sidebar
  • footer

Within layout-fixed.css, you will find the content set to 960 pixels wide with no sidebars, 760 pixels wide with one sidebar, and 560 pixels wide with two sidebars. Each sidebar will be 200 pixels wide.

With layout-liquid.css, the minimum width of the site will be 960 pixels wide, and each sidebar will still be 200 pixels wide, but the content will take up the remaining width within the page by default.

To completely change your look and feel from the two sidebars and a content structure, change the layout-fixed.css or layout-fluid.css to something more inventive.

page-backgrounds.css

Set your background colors or images in page-backgrounds.css for the body, page-wrapper, page, header, main content area, and footer. This is pretty straightforward.

tabs.css

Zen provides default styles for your primary and secondary menus. Edit the CSS tab settings here to change the font, margins, and backgrounds – for instance you may want to connect the background color of the highlighted tab to the content area.

messages.css

This is for styling Drupal messages, warnings, and errors – if you don’t change these, they can be really out of place in your Drupal site.

pages.css

This CSS file holds a lot of individual styles for your page.tpl.php template. This is not for major structural changes – those should be in layout-fixed or layout-liquid, but instead for visual details such as font size, colors, alignments and minor margin and padding adjustments. This is one of the main CSS files you will have to spend a lot of time in to get your site looking correct.

block-editing.css

Used for Zen’s hover block editing feature – no need to change this CSS file

blocks.css

Edit your block’s CSS in here. Provide default settings for all of your blocks, or customize the appearance of individual blocks with settings for each Drupal core block.

navigation.css

Styling for Drupal’s Primary and Secondary menus – nothing in here by default.

panels-styles.css

Styling for the Panels module – nothing in here either.

views-styles.css

Styling for the Views module – again, up to you to provide anything you need.

nodes.css

Styles for nodes – you can provide different styles for published or unpublished content and for sticky nodes. When you create a new node type, that node is given a style of node-type-your-new-node-type-name, and you can customize the styles by node type in nodes.css as well.

comments.css

CSS Styles for comments – you can do all kinds of interesting tricks with CSS here, such as zebra striping odd and even comments, highlighting non-anonymous comments, or marking comments that the current user hasn’t read.

forms.css

The form styling not only includes defaults for the standard HTML form controls, but also contains styles for the search box, login, and Open Id Login.

fields.css

Contains styling elements for Content Construction Kit (CCK) fields – this is left up to you to decide.

print.css

A nice printer-friendly CSS file.

Hopefully you find this description of the CSS files included with the Zen starter kit useful!

Categories
Drupal Planet

Using Drupal’s Views as a JSON Web Service with the REST Server

Drupal 6 does not have web services built in – instead they are part of the Services module. The Services module enables your Drupal installation to provide data to clients such as Flash, Javascript AJAX clients, or in my case, an iPhone application.

To use the Services Module, you will have to install additional servers to communicate with clients – for instance, the REST Server and the JSON Server. Using Three20’s GitHub example as a guideline, I can see that JSON parsing is a lot simpler on the iPhone than XML, and I’d prefer to stay away from XML anyway. There is also a native iPhone plist server for Drupal, but at some point I may create an Android client, and there’s no reason to limit myself to iPhone only.

This led me to the JSON Server as the solution, but that turned out to be a dead end. I’ve had much frustration with the JSON Server – from what I can tell, it really doesn’t work. I’ve gotten lots of 404 errors and not much else. From its Issues on Drupal.org, I’m not the only one with JSON Server issues. Luckily the REST Server offers a JSON interface as well, by just appending “.json” to the end of the GET URL.

Getting JSON representations of individual Drupal nodes with the REST Server is very straight forward – make a GET request to http://<yourserver>/services/rest/node/<node-id>.json where <node-id> is 1.

Some gotchas here are that even if you don’t care about securing access to that node (because it’s public content on your Drupal site anyway), you need to enable Key authentication for your services in Drupal and then turn it off in the Services Settings.¬† You also need to remember to enable the Node Service module, and ensure that the “load node data” permission for the node_service module is allowed for anonymous and logged in users (if you want it to be public, of course). Any of these things not being done properly can lead to a 404 error when you make the REST call.

This all works well for loading one node at a time, but I’d like to show information from multiple nodes on one iPhone screen. And I’d like to make that show up as quickly as possible – so that means that rather than making multiple HTTP calls to Drupal over the network, I’d like to just make one call to the server.

Drupal’s views are perfect for this – views are nothing more than a layer on top of SQL, and what I want is basically a few fields from each node reference on my main node. The nice thing here is that I can develop and debug my view from Drupal to make sure it outputs the data that I want first, and then simply load that view into the iPhone app and work with the data there. But to do that I need to have a little chunk of middleware that connects the iPhone app to the Drupal view – this is where the Views Service module comes in. Enable Views Service, and the Services admin settings will show a views.get method. Using the admin interface, you can experiment with the arguments needed to get your view to work as a service. Of course, this is not an endpoint you can actually use as a service, but just an admin tool.

To actually load a view using the REST Server, I had to do some serious research. The best source of information was an issue for the Rest Server where the developer answered – http://drupal.org/node/570778#comment-2547806 another question. Unfortunately his answer included a typo that threw me off for a while, so here’s what you actually need to do –

POST to /services/rest/service_views/get.json

with the arguments ‘view_name’ and ‘args’ – you can test these from the admin interface. Using curl, the request looks like this from the command line:

curl -verbose –data ‘view_name=your_view_name‘ –data ‘args=[your_args_1,your_args_2]’ http://your_server_name/services/rest/service_views/get.json

Let me know if this helps you out with the REST Server, Views, and JSON – this was a tricky subject to google for.

Categories
Drupal Planet iPhone Development

Three20 – Adding Title to Table View Controller after Datasource Loads

This is actually a pretty minor little detail, but it’s something I spent about half an hour getting to work, so hopefully I can save a few people some more time.

Most of the examples with Three20 are pretty static – the controller loads the same thing every time, so you can hard-code the title to the controller in an init() method.

In my case, many of the controllers actually correspond to Drupal CCK content types, so instead of displaying a generic “Information” title, I’d prefer that the TTTableViewController display the Drupal Node title as the title for the user.

I’ve already done all of the work of loading the Drupal node as JSON and parsing it on the iPhone into an NSObject (Trail). The Trail object is a child of my TTModel (TrailModel), which is then the model of my TTSectionedDataSource (TrailDataSource). To make things confusing, the model for my TTTableViewController(TrailViewController) is the datasource.

I expected to find a title property on the TTSectionedDataSource, similar to the TTPhotoSource, but there wasn’t one, so I had to dig a little deeper. I knew I had to wait until the model finished loading so I had a business object to ask for the proper title, and I’d also found earlier that there is a pretty nice system of messaging set up in Three20 already.

In this case, the model will notify the model view controller that it is finished loading and displaying, and then I can override that method ((void) didShowModel:(BOOL) firstTime)

There really isn’t much to it other than putting whatever code I want into the didShowModel() method – I grab the title by going through the datasource to the model and then to the value object, rather than by writing a series of getters that dig down into the value object.
[plain]
– (void) didShowModel:(BOOL) firstTime {
[super didShowModel:firstTime];
TrailModel* model = (TrailModel*)[self.dataSource model];
self.title = [[model trail] title];
}
[/plain]

Categories
Drupal Planet iPhone Development

Building an iPhone App that works with Drupal

One of my projects is working on an iPhone app that will pull its content from a Drupal 6.x installation. Instead of authoring, editing, and publishing content and images in two different places, the iPhone app will use the content directly from the Drupal CMS, using Drupal’s Services Module and JSON.

I did some pretty extensive research on this, as I thought there had to be some sort of generic iPhone app client for Drupal already. Unfortunately, there are more people looking for this problem than there are solutions. The closest thing I found was BeerCloud for Android and Drupal. They provide a library for Android mobile apps,¬† drupalcloud, but I haven’t seen anything for Cocoa Touch.

As I dug deeper into the problem, I figured out that the reason there wasn’t a generic Drupal iPhone app client is that there wasn’t an easy way to map a Drupal Node to the iPhone device and have it be a usable mobile application – some customization is going to be necessary, especially if you are using CCK with the node to have custom fields.

What I’d like to do on this blog is present an ongoing blueprint for how I’m building my iPhone app, along with the changes and modifications I’ve made with my Drupal installation. Hopefully it’s useful to at least one other person, but it also gives me a place to record my design notes and thoughts.

The most important decision I’ve made so far has been to use the Three20 framework for my iPhone app – this is the framework that the Facebook for iPhone application is based on. The features of Three20 I’m most excited about are the network-aware data model and the ability to use URLs for in-app navigation.

Categories
Uncategorized

Impressed by WordPress so far

I’m currently working on several Drupal 6.x web sites, but to broaden my knowledge, I decided to use WordPress for my personal/professional web site. I don’t want to get tied to just one way of doing things or thinking, and I’d also like to be able to recommend the right CMS for a project.

Drupal was actually easier to install than WordPress¬† 3.0.1, which sounds funny, but I was really surprised that WordPress didn’t let you set up the database from a PHP page instead of from a configuration file. Not a big deal for me, but it seems like that’s the norm for PHP CMS installs these days.

The out of the box WordPress Post creation UI is much, much cleaner than the out of the box Drupal 6.x Post Creation UI. Partly this is because WordPress is more focused, but there is a lot you have to do to Drupal just to get a WYSIWYG editor in place with image uploads – try it and see. And even when you do get that set up for a content creator, the UI is complicated and difficult to understand.

So far I also like the WordPress Admin dashboard – Drupal 6.x needs something similar out of the box, where modules can register alerts or notifications of things that need to be done. I had something similar in a Ruby on Rails web application that I built a few years ago, but it was all custom code.

I’m still exploring WordPress, but I don’t intend to do a lot to this site with plugins or themes, so I probably won’t get to see a lot of the differences between Drupal and WordPress with extensibility.