I'm kind of struggling here. When I first took on the project of developing a website for my friends in this student society I was turned on to drupal. I browsed the modules available and the features they seemed to be able to implement and felt I could deliver the features wanted. Sadly now stuck in layers of abstraction and let down by the apparent limitations of modules I thought were more flexible that's looking unlikely. Frankly I'm on the verge of quitting any idea of using drupal and coding from scratch in PHP even though I know it will make it harder to maintain for who ever comes after me, keep me from implementing advanced features like live chat and even though I actually really really dislike PHP (give me c++ any day).

What I am attempting to make is a highly relational site where almost all of the content is interrelated in some way rather like a typical database. I want a central 'library' of items, for simplicity sake lets call them TV shows, these are referenced by auto generated IDs that are hidden from the user. This is because I can't guarantee title uniqueness (remakes etc). These are referenced by three content types. In all of these cases the content that references this 'show' has to do so with out requiring the user to know the ID. He has to be able to search for it by name & date etc. After that the reference to the show needs to be displayed in this new content type (for example a review of the tv show) under the shows name (not its ID) and offer a link to that record. I've been trying to use entity reference, entity reference dynamic select widget and auto entity label to do this and failing miserably.

This is key because I need the reference linking to this (TV show like) content type to do a lot of heavy lifting. Around it I plan to build a review system, a list of DVDs like things available to loan and a system of records linking shows to events at which those shows have been shown (which I'm using date and calendar for atm). I then plan to attach a poll to each show at a given event and a lending system to the list of loan-able items. Currently I'm looking at MERCI to do that but it's not a close match to my needs.

Please give me your honest opinion. Is this doable in drupal or would I be better off looking at a custom solution? (baring in mind I don't have huge amounts of spare time for this project.)

Comments

WorldFallz’s picture

I don't see anything in your description that couldn't be handled by drupal. And the very fact you mention You don't have a lot of spare time would indicate that you're better off using a CMS than coding from scratch. That said, there is a learning curve for drupal and that has to be factored into the mix.

More often than not when I encounter coders struggling with learning drupal, it's precisely because they are coders and trying to work with drupal from that mindset rather than adapting to the 'drupal way'.

And you don't mention much about your lending use case, but from what you've written here, I would think MERCI would be way way overkill for just a simple lending library. Maybe give agreservations a try.

Unique ID's are built-in to content types so that shouldn't be an issue. And when it comes to linking items, I generally use entityreference, entityreference_prepopulate, and auto_nodetitle. However, if you're not using content types (but I don't see any reason not to based on your description), you would need entity_label which I haven't tried yet. Taxonomy is also a way to link different things across content types. For ratings there's fivestar or rate. And of course, the great views module for any and all listings and custom searches (done with views exposed filters).

Honestly, I don't see anything here that couldn't be done pretty easily by someone who knows drupal, so it's likely the learning curve that's giving your problems, rather than any actual limitations of drupal itself.

That's doesn't really help much... it's pretty much up to you whether or not it's worth the learning curve. However, I've recently come from a project for which I had to use c# and omg I hope I'll never have to that again. Something not much more complex than what you describe here took like 6 months to code completely from scratch (including all the jquery and manual ajax and whatnot) and would likely have taken at most a month with drupal (if not less).

And I noticed you only just joined drupal.org-- so you've obviously not being seeking help here. Often a couple of targetted posts can get some good responses and get you past a bump or two in the road while climbing the learning curve.

pkej’s picture

There are a few building blocks in Drupal you need to learn. The first is the Fields (formely known as CCK). The other is Views.

The Fields UI lets you create content types, which for all intents and purposes are your database tables. They all produce nodes, and each node as an unique id.

Download Views and enable the Views UI (it will be part of the Drupal 8 distro), which lets you create views, which for all intents and purposes are your database reports. You can choose if you want to produce these as pages, blocks and a few others.

Add the modules WorldFallz mentioned (but add the http://drupal.org/project/references_dialog module as well, a super short tutorial) and you have what you need for your project.

For a simple walk through on how to use these different parts one good place is to start with some video tutorials. Wunderkraut (formely NodeOne) has some tutorials on their site, for general Drupal learning: http://nodeone.se/sv/node/36, for references this one: http://nodeone.se/sv/node/30. References can be thought of as Foreign Keys.

The references dialog lets you use views to look up other content, and in views you can use filters, thus enabling you to use text and dates. Oh, and you need the date module and perhaps the calendar module (for js calendar popups to date fields).

The entityreference_prepopulate module lets you send in data to a new node creation page, for example an id for another content. So say you are in a "TV Show page" there would be a link for creating an "episode" which would go to a node creation page where the show would be filled in already.

The autonodetitle module hides the title field and lets you create them based on placeholders or code. So the episode page could have a Name field and the title would be generated like thus "TV Show S01 - E01 Episode title" and fetching the data from the relevant source fields.

You might also like to look at conditional fields and computed fields, the first hides or shows fields in the creation pages based on values in other fields. The second computes values for you, based on PHP code. Search and you shall find pages describing them and to learn how they can do a lot of stuff.

Using Drupal for your project certainly seems feasible, in fact this is exactly the kind of stuff that is fast to do in Drupal. I called content types tables, views for reports, and references for foreign keys. If you want to take it further you can look into Rules which might be akin to triggers.

I also suggest that you search for modules using filtering by popularity, as that will give you an idea of how likely it is that the module will "survive" to Drupal 8 and into the future, as almost every major release demands some kind of maintenance of existing modules for them to work.

Best of luck, an do look into the tutorial videos available.

Paul K Egell-Johnsen

CodeWarrior-1’s picture

I'm sorry but references dialog isn't what I was looking for. For starters it only seems to work from a relation parent not with an Entity reference field. I definably want a field pointing to the other content type. I need something more like dynamic select widget only that doesn't seem to work. Presumably because it's not finished yet. The heart of the problem is drupal seems to be built on the assumption the data in fields is always going to be human readable. What is needed is a sort of interface layer you can program that sits in front of content creation, editing and viewing that can probe the value of the contents fields as well as the the fields of other content and use it to link between the human readable dummy fields and the non human readable actual content fields. But given that doesn't exist I'd settle for something like dynamic select widget that works. Computed Field has potential but I'm not sure if it could dump its result into an entity reference field and even if it could I'd rather have it dump the likely candidates into a list and let my user select one.

johnpitcairn’s picture

I'm pretty sure that what you need is entityreference, but instead of using the default autocomplete to lookup your "shows", you should use an entityreference View to include whatever information you need in the autocomplete popup. To allow the user to distinguish between two shows with the same title, you could add the date field to the view display. The user never needs to know the show ID, they just search by title.

You shouldn't need to compute anything to give you a unique reference ID for a show, the node ID is exactly that, and is used as the entityreference key.

Finally, when displaying the content of the referenced show on the parent page (manage display), if a linked title is not sufficient you can use rendered entity as the display mode, and perhaps look into using Display Suite to create a custom view mode for the show content type (if the default, full content or teaser view modes are not sufficient).

So: Drupal core, Entityreference, Views, and (maybe) Display Suite.

CodeWarrior-1’s picture

I asume you mean entity reference View. I've installed it and view now pops up in the list of widget types but the widget doesn't show up when I try to create some test content. I guess I need to assign it a view but none are listed as available. No view template or view type turns up associated with the widget. I'm not sure how to create a view to work with this widget or even if I can?

johnpitcairn’s picture

No, entityreference supports the use of a view natively. Use an autocomplete widget, but under "edit" for the field, your entity selection mode should be "Views".

You first need to create a View and an "Entity Reference" display in that view. In this you add a filter on the target content type (and published, probably), and add the fields you want to see in the autocomplete. Under Format:settings you can define the fields you will search on. Fields can be hidden if you want to search on them but not display them.

Save the view, and it will be available for selection as entity selection mode in the entityreference field edit.

johnpitcairn’s picture

Oh, you will need to use the dev version of entityreference to search on fields instead of title. See #1691612: Autocomplete is searching only on entity properties (not fields)

CodeWarrior-1’s picture

sir it works like a dream. thank you so much :)

johnpitcairn’s picture

Half the battle is figuring out which modules to use. In the early stages of learning Drupal you'll probably use far more of contrib than you need, because there can be a lot of overlap between modules. But in general, Views is always your friend.

WorldFallz’s picture

actually with coders new to drupal I find the biggest obstacle to overcome is the urge to code everything (and without using drupal apis no less) rather than rely on existing modules.

CodeWarrior-1’s picture

in a related issue I have several different type in my database of 'shows' as encapsulated in the 'type' field. Some fields are only relevant depending on type. For example if the type is tv series I might want a season field to identify the season. If it's a film I might want the 'number in series' field if it's part of a trilogy etc. I can use conditional fields but with a lot of types I'd have most fields being hidden most of the time. Is there a way to make the label dependent on the value of type so the same field could be 'season' for a tv series but 'number in series' for a film etc?

johnpitcairn’s picture

Is type a taxonomy reference?

I think if you don't want to use conditional fields, you'd need to write your own simple jquery behavior to change the label. That would likely need to go in a custom module (or less ideally, in the theme's template.php), and you'd use hook_form_<type>_node_form_alter(), adding your jquery as a new array element at $form['#attached]['js'][].

CodeWarrior-1’s picture

no type is a list (text) field. That seemed more logical to me since I want to refer to it across content types and want to make it required ... I don't believe there is such a thing as a required taxonomy? If I require a custom module I'll have to balance the cost to development time with having a really ugly generic field name that's not intuitive and probably not being able to change it later and then balance that against having lots of empty fields in my database if i just use Conditional Fields to hide lots of different fields.

johnpitcairn’s picture

You can have a required term reference field, as autocomplete, checkboxes, select menu.If you want to have a page displaying all shows of type X, then taxonomy gives you that right out of the box, and the "teaser" view mode can be tweaked accordingly. Views also provides a default view that emulates the taxonomy term page, and you can tweak that. If you're just using a list field, then you have to build things yourself from scratch (admittedly not that hard with Views, but still).

I think it would probably take less time to do the custom module/jquery label switching than it would to setup all the extra fields and configure conditional behaviors for them all. I've been down that route, it's no fun and a pain to maintain.

CodeWarrior-1’s picture

Yeah ... I have no idea how to write a module but that would be the most elegant solution. They are in PHP right? The last time I looked at PHP was 2007. Jquery would be far easier for me to code but I bet the first thing my successor does is change what ever theme I put on. Any good 'how to write a module guides you can recommend?

johnpitcairn’s picture

Google is your friend ... but all you need is the .info file and the .module file, plus your custom jquery file, all contained in a directory under either /sites/all/modules or /sites/yoursite/modules.

If your jquery is inserted via module, then changing the theme won't affect it.

The .module file just needs to start with a php open tag (no close tag), and contain your custom form_alter() function. Something like (untested):

<?php
/** 
* Implements hook_form_FORM_ID_alter().
*/
mymodule_form_CONTENTTYPE_node_form_alter(&$form, &$form_state) {
  // Add your js file to the form's js array. Use the API to get the module path.
  $form['#attached']['js'][] = drupal_get_path('module', 'mymodule') . '/mymodule.js';
}

Replace mymodule with your actual module name, and CONTENTTYPE with the machine name of the content type.

johnpitcairn’s picture

Your jquery file should follow Drupal standards and be wrapped in a closure, adding a Drupal behavior:

(function ($) {
  Drupal.behaviors.myModule = {
    attach: function (context, settings) {
      //   Runs at document.ready(), do your stuff.
    }
  }
})(jQuery);
CodeWarrior-1’s picture

Frankly I'm nearly there. The form now works perfectly but I'm really struggling to get the content type to display right when I view it. I'm guessing I need to use one of the following hooks hook_entity_view_alter or hook_node_view_alter but the documentation on both is ... far from great. There's no outline for the structure of $build in either case and I can't find one anywhere online (believe me I looked). Can any one advise me whether I can use either of these hooks to alter the label displayed based on the value of a nodes field and is so where in $build I'd find the relevant variables?

johnpitcairn’s picture

Just hook_node_view() would be my choice, short of writing a custom field formatter. You probably want to run before any of the theme rendering kicks in.

Take a look in $node->content['field_name'].

CodeWarrior-1’s picture

You've all been really patient and I thank you. I have one more issue. I'm now making a content type that lists items in a library. So I might have an entry in my tv show / media database 'the simpsions', then an item in the library for a vhs tape of 'the simpsions' episodes x to y. So my item content type has entity reference field and I want to insert a bit of java script into my form that every time the entity reference changes it looks up the relevant field in the new referenced node and modifies labelling and visibility accordingly.

I could write a custom bit of PHP to directly query the mySQL database and let my javascript call it with get but I wondered if there was a 'drupal' way for javascript to query nodes other than the node who's form they're integrated in? That way changing the password on the database won't break my module.

regards
peter

johnpitcairn’s picture

Register a path using hook_menu(), of type MENU_CALLBACK, with a page callback function that generates the data you need. Your jquery makes a $.ajax() call to that path.

Cheat: your page callback could just programmatically load and echo a view, if you want future admins to be able to tweak it without writing code. Look at views_embed_view() in particular. But even if you turn off as many of views' display wrappers as you can, you'll still get a lot of html cruft back with that which you'd need to extract the data from in jquery (easy enough if you add specific row/field classes).

If you'll be querying the Drupal database yourself in the menu callback to echo simple JSON or such, use the Drupal APIs for that: db_select(), db_query(), and perhaps (if you will load the whole node/entity anyway) EntityFieldQuery.

CodeWarrior-1’s picture

thanks eventually that approach yielded fruit works like a dream!