Károly Négyesi (via DrupalFire)
The entity config query is in and the aggregation query system is ready, and it's surprising how little new code was necessary for it -- mostly a little refactor of the existing SQL implementation to make it more reusable and of course a lot of tests -- written with the help of dawehner, thanks! There are a few big issues left: split the entity controller into a CRUD controller and the real controller. Once users become EntityNG, roles need to use the existing entity reference item. Same for taxonomy terms and their hierarchy.
Many issues are progressing/being done: the Field API to CMI conversion is nearing some 600kb. Field and entity types are being converted to the new entity API -- node is making huge progress, and it's definitely the worst. Entity reference made it in. We now have metadata for config inspired by kwalify.
As it is now firm that a MongoDB DBTNG driver will be necessary, I have reopened an old issue and written a small patch to allow database drivers outside of the core directory. This issue met some political resistance (I can't claim I found any technical reasoning in the issue aside from "we cannot do that") so I am not quite sure whether it will make it in -- I have asked Dries to decide on it to cut the chase. As we would need to instruct people to put the DB driver in the right place anyways, at worst the drivers will go besides the core drivers as they did in D7, it's just going to make core upgrades harder. But then again, if you use git, even upgrades won't be harder, so it's truly not a biggie. Just another bitter day in the core queue -- there are a just bit more of them than I'd like in this cycle.
Of course, the big hurdle of making Views default to entity queries is on the horizon as well, and I had some conversation with dawehner already about it. This is a bit hard to put to writing because my thoughts are still forming. So, one important part of Views is the query builder, especially the default SQL one. However, entity query contains another query builder and once the aggregation queries get in, their power will roughly be equal. Of course, not everything is an entity and there will still be outlying cases that the SQL query engine can do but the entity query engine can't. So, we want to show the full gamut of possibilities to the end users in such a crafty way that entity queries are ran when possible and the Views SQL query builder kicks in only when necessary. Of course, if an entity is not in SQL then SQL queries are straight out. Now, Views does not easily yield to all this, some changes to the way data is defined will be necessary. We need to take a good hard look at the way sort/filter/etc handlers are created too so that within the confines of single inheritance we can still reuse them. Thankfully, there's ample time for this past feature freeze -- all the way till API freeze.
Angie Byron (via DrupalFire)
As Gábor pointed out, now's the time to help make Drupal 8 more unified and user/developer friendly. A great way to do that is try porting your modules, now, while there's still time to fix the APIs before code freeze.
Here's the video and slides from my Upgrading your modules to Drupal 8 talk at DrupalCon Sydney 2013, featuring the Pants module.
Slides: PDF | PPT | KEY (the canonical version)
But wait, there's more! ;)
The DrupalCon talk was only an hour, so wasn't nearly long enough to walk through the actual steps involved in each API. However! Thanks to the magic of Git (and particularly git rebase -i ;)), you can actually step through each step in the porting process.
$ git clone --recursive --branch 7.x-1.x http://git.drupal.org/project/pants.git
This will get you the 7.x version of the Pants module so you can look at code that hopefully looks somewhat familiar. :)
From there, you can step through each of the steps as follows:
$ git branch -a
* 7.x-1.x
8.x-01-basics
8.x-02-tests
8.x-03-config
8.x-04-blocks
8.x-05-router
8.x-06-twig
8.x-1.x
$ git checkout 8.x-01-basics
$ git log
Note: Each commit message cross-references the change notification for that particular issue. (They're more granular at the beginning than at the end; sorry. :\)
There's also kind of a "brain-dump" of notes if you want to present these at your local user group: http://drupal.org/node/1911346
Note: This is accurate now, but not necessarily tomorrow or especially not next week. ;) Nevertheless, I hope this is able to help someone out there get involved in Drupal core! :) There's a global sprint happening tomorrow!
Lullabot (via DrupalFire)
Lullabot Re-Launches a Responsive GRAMMY.com for Music’s Biggest Night
Lullabot is excited to announce its fourth annual redesign and relaunch of GRAMMY.com! Just in time for the 55th Grammy Awards this Sunday, February 10th, this year's site features a complete redesign, as well as an upgrade to Drupal 7 leveraging Panels and Views 3.x, some cool, fullscreen, swipeable photo galleries and other mobile-web bells and whistles. The site is also fully responsive, allowing the 40 million+ expected viewers to stream, share, and interact across any web or mobile device. Special congratulations to Acquia for hosting GRAMMY.com for the first time, as well as to our good friends over at Ooyala for once again delivering the site’s archive video content, and to AEG for delivering the live stream video via YouTube.
Simultaneously tune in to every aspect of music’s biggest night so you won’t miss a thing: awards news, video, pictures, artist info, Liveblog posts, thousands of tweets-per-minute and behind-the-scenes action.
The GRAMMY Live stream starts tomorrow, Friday February 8th at 5pm ET / 2pm PT, so you can spend all weekend with the website as you gear up for the CBS telecast on Sunday night. Don't miss any of the GRAMMY action this weekend!
We'll be watching and tweeting along from @lullabot. Follow us on Twitter and let us know what you think.
Four Kitchens (via DrupalFire)
The popularity of responsive web design is constantly exposing behaviors that web browsers have gotten away with over the years. Many of these behaviors — while brilliant for a single-screen web — become a direct hindrance when dealing with the multi-screen extravaganza that we face now.
One of the most hotly debated topics is responsive images. This was a topic widely exposed by Filament Group due to their work on the Boston Globe, and it continues to be an issue for every bandwidth-conscious site today.
History
The foundations of this topic have been hotly debated and oft explored in the past year, so here’s a list of articles that capture the history of responsive images and demonstrate the challenges developers face on a modern site:
Today’s solution
Whatever the final outcome of the standards process, if you find yourself needing responsive images today there are several approaches, the most successful of which is currently the element.
In a nutshell, is a brand new element with behavior that is — for now — controlled by JavaScript. This allows us to achieve all of the goals for a proper responsive image request: avoiding image prefetching, preferring author-controlled image selection, and ultimately only downloading a single image (instead of a fallback plus larger version)
Picturefill is its own open-source library, available on Github.
Implementing responsive images on a Drupal site
The latest responsive site that Four Kitchens launched, Full Plate Living, tightly integrates responsive images with Drupal content. The methods for doing so are thankfully rather easy, but as with all things Drupal there is a bit of a learning curve to get started. Responsive images can be added to content, views, etc. with the help of two contributed modules: Breakpoints and Picture. These two modules rely on Drupal’s core Image Styles module to output images in various sizes using a URL-specific, render-on-demand system.
Configuring breakpoints
In responsive web design breakpoints are used with media queries to determine when new CSS rules should apply to the site’s markup. As its name suggests, the Breakpoints module allows your site to define media queries on which you’d like to take action. The module provides a canonical list of breakpoints that are accessible from the database and thus surfaced to your site’s code. The Breakpoints module also has the notion of a “breakpoints group.” Groups are particularly useful for defining sets of breakpoints that are only relevant to certain parts of the site. These breakpoints can then be semantically referenced by their group name which allows you to reuse breakpoint names between groups, even if the media queries aren’t the same.
In the case of Full Plate Living we had one global set of breakpoints that was defined in the theme’s .info file:
breakpoints[smartphone] = (min-width: 320px)
breakpoints[fourhundred] = (min-width: 415px)
breakpoints[smartphone_only] = (min-width: 320px) and (max-width: 767px)
breakpoints[smartphone_landscape] = (min-width: 480px)
breakpoints[smartphone_landscape_only] = (min-width: 480px) and (max-width: 767px)
breakpoints[small_menu] = (min-width: 430px)
breakpoints[smaller_menu] = (min-width: 421px)
breakpoints[recipes_landing] = (min-wdith: 520px)
breakpoints[user_reg] = (min-width: 625px)
breakpoints[tablet] = (min-width: 768px)
breakpoints[tablet_only] = (min-width: 768px) and (max-width: 979px)
breakpoints[desktop] = (min-width: 980px)
This same set of breakpoints was used in our Sass and JavaScript files (with response.js) to provide a consistent list of breakpoints for all of our front end code to interact with. Unfortunately this list was duplicated in the three places; a future implementation might use a build tool like grunt to keep the global breakpoints list in one place and update the .info, Sass, and JavaScript definitions appropriately.
Additional breakpoint groups were added for content types so that the amount of markup required for responsive images could be kept down (one breakpoint means two picture options: the default, and the one defined for the breakpoint).
Configuring image styles
Core’s Image Styles are used to format the images that will be used in the picture element. It’s a good idea to give the image styles meaningful names so that configuring the Picture module is more straightforward. In the case of Full Plate Living we generally used two image styles per page: STYLE__full for images delivered to large viewports, and STYLE__mobile for images delivered to small viewports.
Configuring Picture
The Picture module ties information from Breakpoints and Image Styles together and ultimately provides the markup and picturefill JavaScript that will be used on the page. Each breakpoint group will have a tab on the Picture admin page that lists its breakpoints and provides a dropdown for each one to specify the image style that should be used.
Finally, when you’re defining the display style for your image fields you will choose “Picture” as the formatter for the image. The settings for this field will allow you to choose the “picture group” and a “fallback” image style. The fallback image style will be used if no breakpoint conditions are met. If you’re building mobile-first, this would be your base mobile style definition and should be the smallest image that will be delivered to the client.
Show me the data
To demonstrate the advantages of the element we captured data from the Full Plate Living recipe landing page. See those beautiful, gigantic images below the search? Such a huge image is not needed for the same effect on a small screen. Implementing resulted in a difference of 157K out of a max page weight of 746K. Here are the two network waterfalls:
Mobile
The three images in this screenshot that start with 2012 are the mobile-formatted images. They total approximately 40K at the default breakpoint.
Desktop
Looking again at those images with the same 2012 prefix, we see a total of 197K, meaning we are preventing the site from serving mobile users with approximately 157K of data that they don’t need.
You can see that the download “initiator” for the images is a script — not the HTML page — due to the picturefill script modifying the DOM and specifying the image that should be used. This DOM modification causes the markup on the page to differ based on the viewport, visible in this gist.
Div + data-attributes
The element was used on Full Plate Living, but for now it’s considered slightly more future-proof to use elements with data attributes.
The picturefill script and Picture module both currently use the method, so although your markup will look different, the end result will be the same.
In conclusion
We all recognize the need for a responsive image container on the web. Today’s solution might look very different from tomorrow’s, but the need for device-optimized media will continue to grow as fast as the variety of devices accessing the web. Just hang on, remember to test, and enjoy the ride!
Credits: this article was co-written by Elliott Foster.
Lullabot (via DrupalFire)
Design Principles for a Multi-device World
Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius -- and a lot of courage -- to move in the opposite direction.
— Albert Einstein
I would argue that a huge part of that genius Einstein refers to can be found in clarity of purpose and principles.
We all wind up in those situations where we're focusing on technical details, implementation and points of process, and missing the bigger picture. I confess I've been there far too often. When we find ourselves in those situations as designers, it's important to have some guiding principles we can remind ourselves of and even share with our team and colleagues. Guiding principles can help get everyone on the same page and make it easier to work through the details of process and implementation. They're no panacea, but they've certainly helped me maintain my sanity.
Below I've documented some of my emerging, fundamental design principles. These principles have helped guide me in this brave new world of a bazillion devices and amazing possibilities. Hopefully they'll be helpful to you as you hone your design process, document your own principles, and face challenges along the way.
Gábor Hojtsy (via DrupalFire)
Many of the Drupal 8 core APIs are shaping up now, and as Larry Garfield likes to say "we are still not ready porting Drupal 8 to Drupal 8". Meaning that the new APIs introduced are not used widely at all places where they would be applicable. Views is in core, but not all listings are views, router configuration instead of menu hooks are in core, but most modules use menu hooks, and so on. We of course target the final Drupal 8.0 release to have these conversions done, but we need more help to do them. Let me highlight items that interest me most as the multilingual initiative lead (but most of these rhyme with multi-channel publishing / web-services efforts as well).
Help convert content-like things to content entities
Drupal 8 has a new improved Entity API to manage content entities. What better opportunity to get to know the new content handling APIs than being involved in porting core components to it? Web services and multilingual are both fundamentally in need of a unified handling for content-like stuff in Drupal.
Comments have already been converted to the new entity API (http://drupal.org/node/1778178) which can serve as an example for conversions elsewhere, namely nodes (http://drupal.org/node/1818556), users (http://drupal.org/node/1818570) and so on. See the full list of conversion issues at http://drupal.org/node/1818580. Once these conversions are done, we still need to apply multilingual property handling to do such basic things as editing titles on nodes in different languages (http://drupal.org/node/1498674).
While the existing entity types need conversions, there are also other content-like things in core that need to be converted to entities proper. For example aggregator feeds (http://drupal.org/node/293318) have been converted to content entities but more needs to be worked on. Hands are needed to help with converting menu links (http://drupal.org/node/916388) and custom blocks (http://drupal.org/node/1871772) as well.
Learn Drupal 8 configuration by porting things to the configuration system
The new configuration system in Drupal 8 is great in unifying all configuration elements under one system instead of custom one-off database storages and APIs for configuration.
There is a laundry list of system settings forms to convert to configuration at http://drupal.org/node/1696224 including locale module settings, file system settings, etc. still to be done.
Drupal 8 also comes with configuration entities, which store their data with the configuration system (and are not fieldable). Some of the previously custom coded features such as views, menus (http://drupal.org/node/1814916) and contact form categories (http://drupal.org/node/1588422) have been converted to configuration entities. Others like languages are still to be done (http://drupal.org/node/1754246). Track all related issues at http://drupal.org/node/1802750.
Learn the new configuration schema system by writing schemas for configuration
A configuration schema system was just recently added to core (see http://drupal.org/node/1905070 for documentation and examples). Some configuration files got a schema defined in the initial patch, but there is still more work to be done to adopt this and complete. For example, only some of Views got schemas written, and we need to complete that (http://drupal.org/node/1910606). The meta issue to track and find schema issues is at http://drupal.org/node/1910624.
Why get involved?
I think this is a unique opportunity to (a) get to know Drupal 8 early (b) still have a chance to shape things in Drupal 8 where you find them confusing (instead of bragging about them too late when there is no chance to change) and (c) help Drupal 8 become the great consistent platform we all want it to become. Better web services features and dramatically more extensive multilingual features are also a huge plus!
How to get help if you get stuck?
Most of these issues have someone who got it started and you can find the people who worked on previous complete conversions that I linked to above. Find these people on IRC, get involved in virtual meetings, ask at core mentoring hours. Sometimes all is needed is reviews, help testing or help writing tests.
Thanks for all your contributions!
Four Kitchens (via DrupalFire)
Everyone does it.
There’s a piece of JavaScript that will only be used on one page, perhaps to provide some unique interactivity. It’s probably attached to a View or maybe a unique node ID. It’s so easy to toss in a drupal_add_js() and move on — or worse, throw the code in your theme. Wouldn’t it be nice if you could inline all these one-use scripts and make them appear only the page they’re needed?
Inline on the Fly
Here’s an easy way to inline scripts without losing the ability to edit them easily. We don’t want our code sitting in a PHP string so we create and maintain a real JS file, and use file_get_contents() to grab it whenever the appropriate page is built.
// Ensure this JS ends up inline at the bottom of the page
$options = array(
'scope' => 'footer',
'type' => 'inline',
);
// JS lives in its own file but is included inline when page renders
$js_code = file_get_contents(drupal_get_path('module','my_module').'/my_code.js');
// Add JS to page
drupal_add_js($js_code, $options);
Optimized pages + organized code
I often find myself using hook_views_post_build() to apply this behavior when a specific Views display needs some custom JS to function properly. That way I don’t have to worry about the path, it just works anytime this View is used.
Avid Features users know it’s much more maintainable to keep the JS in its own file next to the View instead of stuffing it in a Views footer, or worse: tossing vital code for components into the theme’s “main” (read: only) JS file. Putting code in a theme file can seem swell until you copy a Feature for use in another project and just can’t figure out where that JavaScript went.
/**
* Implements hook_views_post_build().
*/
function my_feature_views_post_build(&$view) {
$has_run = &drupal_static(__FUNCTION__);
if (!$has_run) {
switch ($view->name) {
// Check for the relevant View(s)
case 'my_view':
// Check for the relevant display(s)
if ($view->current_display == 'my_block') {
// Ensure this JS ends up inline at the bottom of the page
$options = array(
'scope' => 'footer',
'type' => 'inline',
);
// JS lives in its own file but is included inline when page renders
$js_code = file_get_contents(drupal_get_path('module','my_feature').'/my_code.js');
// Add JS to page
drupal_add_js($js_code, $options);
$has_run = TRUE;
}
break;
}
}
}
Performance
Inlining a script avoids an http request and is great for frontend performance. However, if you have a page that is uncached and hit continuously, adding disk reads won’t be so great for the actual server’s performance. You can see in the second example there’s a reference to drupal_static(). This is a good way to avoid running a slow Drupal hook more than once per page request. Always make sure to cache the outcome of functions like this one in order to avoid too many disk reads.
Metal Toad Media (via DrupalFire)
Baker's dozen! Shortest episode ever. For ToadCast 013 I was joined by Tyler Ward.
Dries Buytaert (via DrupalFire)
Today is bittersweet for the Drupal Association, as Jacob Redding has transitioned the Executive Director role to Holly Ross. Jacob did a phenomenal job growing the Drupal Association, Drupal.org and Drupal as a whole. Jacob’s special attention to the community has helped create a culture that many of us are proud to be a part of; his passion and dedication for Drupal has always been evident.
Under Jacob’s leadership we have broadened our activities, streamlined operations and significantly increased revenues. The Drupal community members grew by 1143% to 800,000 and we gained 3286% more committers to 23,000 in just three years. That said, our DrupalCon sizes and attendance expanded, which has helped increase Drupal adoption throughout the world. The Drupal Association staff of 12 has settled into Portland and is well positioned in Oregon's active open source community.
With Holly onboard, our vision remains to become the largest open source, non-profit organization that continually increases its support to the community and project. Jacob, thank you for all your hard work and tenacity! I look forward to continuing to work with you in the community.
Metal Toad Media (via DrupalFire)
If you are as open source service provider (Drupal, etc) you have a distinct advantage over many peer in the web development arena. With open source you are leveraging tens of millions of dollars worth of software and bringing that value to bear on even the smallest project you work on; you are part of a vibrant community that has drawn (and continues to draw) both amazing development talent and high-profile customers, who look for your services by name. All of that said, there are some things a CMS like Drupal doesn't bring to the table, and those elements are critical to improving your reputation in the field. So what are those elements?
Lullabot (via DrupalFire)
It's a question we all ask ourselves: What would I do if my site or server was compromised? Security professionals have loads of checklists to follow, and experienced server administrators drill for those moments. As we saw when Twitter.com was recently compromised by hackers, "Reset everyone's passwords, right away!" is almost always one of the important steps. If you run a Drupal site, that particular step can be frustrating. Resetting user passwords one by one is incredibly time consuming, and there's no way to do it for everyone in one fell swoop. At least, there wasn't until the release of the Mass Password Reset module…
Angie Byron (via DrupalFire)
This was originally posted to the "The influence of subtlety" thread on the Drupalchix group back in 2010, but since that was awhile ago now, and since I'm giving a talk on How to Create Ravenously Passionate Contributors at DrupalCon Sydney (and this experience played a huge part) I figured I'd post this to Drupal Planet as well.
Here are some highlights from my first DrupalCon (Vancouver, 2006).
For context, to those who didn't know me back then, imagine the most introverted, shyest, mousiest little geek you can imagine, whose big ice breaker plan was to put on a Google Summer of Code shirt and tuck herself into a corner in the lounge of the hotel everyone was staying at, hoping desperately that someone would maybe, possibly recognize her and come talk to her, since she was too shy to actually introduce herself to anyone. ;) That was me, 4.5 7 years ago. My interactions at my first DrupalCon had a *huge* impact on the future direction of my life.
Note that he didn't end the conversation and then go off and talk to someone else more at his level, nor did he ask me if I was in the wrong room, implying I wasn't smart enough to be part of this interesting conversation. Instead he saw me as an equal who just needed to get brought up to speed, and made a conscious effort to include me in the discussion.
While I wasn't *remotely* at Allie's level (and still am not now, and never will be :)), I saw someone I could relate to, and received confirmation that if someone like that was at home in this community, there was a place for me, too.
This is why all types of diversity initiatives in our community are really important. We want people from all walks of life, backgrounds, interests, skill levels, etc. to see someone they can relate to kicking ass in our community in an environment of mutual respect.
I hope that we can retain this same "spirit" in code sprints today, even though there are several hundred rather than a dozen or so people around the "table". It's invaluable for communicating the Drupal community's "spirit" of contributing, and getting people hooked. :)
I see this come up a lot at the Drupalchix BoFs. A woman will introduce herself as "not a coder" and then go on to detail all of the very-much-code-related things she does: theming, front-end development, putting together code snippets from the repository into something that works, etc. With some encouragement, I think there'd be far less devaluing of skills all around, and more people taking big leaps they hadn't taken before.
The subtlety in these interactions was key. If any one of those instances had gone differently (had, for example, the guys rolled their eyes at Allie when she attempted to explain her approach towards relationship API, or had I been politely asked to leave when I joined the core bug squashing sprint and didn't know anything), I don't know the effect it would've had. But I do know that together, they formed the perfect concoction for getting me totally hooked on the Drupal community and sticking around long-term. :)
I think we can do a lot to off-set this trend by changing some of our default assumptions:
And most of all, if you see someone mousy and shy, hiding in the corner at Drupalcon who doesn't have anyone to talk to, go talk to 'em. You might just change their life. :)
Lullabot (via DrupalFire)
Replicating module_invoke_all and drupal_alter in Javascript
If you've ever written a Drupal module before you're likely familiar with Drupal's hook system. I'm not going to go in to details about how the hook system works, or why this particular pattern was chosen by Drupal's developers. What's important here is what this systems allows module developers to accomplish.
At its most basic, the hook system is what allows me to write a module that enhances or extends Drupal -- without ever having to modify a line of someone else's code. I can, for example, modify the list of blocks that are available on a given page by simply implementing a "hook" function in PHP that modifies the information that was already set up. This approach is one of the things that makes Drupal incredibly flexible!
When you're writing your own custom modules, it is customary to expose these types of hooks for other modules, too. That way, other developers can come along and make minor modifications or feature enhancements to your module by "piggybacking" on your module's functionality, rather than hacking your code. It also means that you don't have to anticipate every possible use case for your code: by providing these extension points, you allow future developers to extend it.
Drupal makes it really easy for modules developers to do this, and it provides a set of helper functions that allow you to easily broadcast these "I have a hook! Who wants to tie into it?" announcements to the world.
Metal Toad Media (via DrupalFire)
All developers know the feeling of accomplishment that comes with completing a tricky section of code. To me that feeling is a distant second to the accomplishment felt when teaching someone else the joys of this hobby/career that I hold so dear. This past weekend (Jan. 26th & 27th, 2013) Portland State University graciously hosted the Chicktech High School Workshop where I had the privilege of being on a team that introduced an entire lab full of high school age young women to Drupal.
Metal Toad Media (via DrupalFire)
Recently I was working with the Drupal services module, and ran into a few hang ups. For my project I needed a rest service that could export xml that matched a specific format, and consume xml and store it in the database for later processing. To do this I created a custom services resource, this was pretty straight forward. I found a few really great sites that explain how this is done. This one in particular is quite helpful. It was when I attempted to customize the output and input that I ran into some hang ups. When attempting to research more about how it is done, I found very little information posted anywhere. In this brief tutorial I will outline how I was able to achieve my goals, and hopefully save you some time.
Dries Buytaert (via DrupalFire)
When we first announced the Spark authoring experience initiative for Drupal in May of last year, we chose Drupal 7 as our target in order to develop the features and get them in front of testers as quickly as possible. After DrupalCon Munich in August, the team shifted efforts towards Drupal 8 core instead, in order to more directly improve the experience of Drupal itself. Since then, we have successfully worked with the community to drive home a redesigned and mobile-friendly toolbar, support for draft revisions, in-place editing, numerous mobile improvements, and have WYSIWYG and unified in-place editing on the way.
This has kept the team pretty busy, however, and so the Drupal 7 version of Spark has not been receiving many updates in the meantime. Olivier Friesse (noisetteprod) of Radio France graciously offered to sponsor work to help things along. Thanks to this sponsorship, we were able to have Théodore Biadala (nod_) of Acquia's Professional Services team spend 3 weeks on getting the in-place editing feature production-ready for Drupal 7, including:
Working towards a stable release for Drupal 7 naturally identified bugs with the Drupal 8 implementation of inline editing, which are being tracked in this issue: https://drupal.org/node/1894454.
In short, the needs of Radio France have brought tremendous value for the entire community, in both Drupal 7 and Drupal 8. If you'd like to try out the work that we've done, download the 7.x-1.0-alpha7 release of Spark or Edit 7.x-1.0-alpha6!
Thanks once again, Olivier and Radio France, for your support! If other companies would like to sponsor further work on Spark, please let me know.
Lullabot (via DrupalFire)
It's a word that can strike fear into the heart of the bravest site builder: Breadcrumbs. Manage them well, and you'll give visitors a helpful visual indicator of where they're at in your site. Miss a detail, and the weird inconsistencies will be more confusing than no breadcrumbs at all. The challenges stem from Drupal's "flat hierarchy" -- by default, almost all pages (including every node you create) live just beneath the home page itself in an undifferentiated pool of content. All of the visual cues it sends to visitors (breadcrumb trails, highlighted parent items in the navigation menus, and so on) start with that assumption until you override them. That's where the Menu Position module helps out. It lets you set up simple rules that tell Drupal where each node type should go in the site's hierarchy, then handles all of the frustrating details automatically.
Recent comments
1 week 6 days ago
1 week 6 days ago
1 week 6 days ago
1 week 6 days ago
1 week 6 days ago
51 weeks 5 days ago
51 weeks 6 days ago
51 weeks 6 days ago
1 year 15 weeks ago
1 year 16 weeks ago