Upgrade Your Drupal Skills

We trained 1,000+ Drupal Developers over the last decade.

See Advanced Courses NAH, I know Enough
Oct 04 2016
Oct 04

Hello fellow Drupalers,

As the dust setteles upon Drupalcon Ireland we wish to invite you to a sunnier location in the middle of the winter.
Come join us for <strong>DrupalCamp TLV 2016</strong> at November 29th in Tel Aviv, Israel !

The conference site ws set up by Royi from Gizra and can be seen here - http://2016.drupal.org.il

We have great sessions proposed from around the world including Bojan from Drupal Commerce and Michael Schmid from Amazee and of course Amitai, Aron, Royi and many more.

Early bird tickets season ends in October 15th so register or get your organization to sponser you asap.

See you in sunny Israel in November!

Dec 02 2014
Dec 02

After working many years with a specific framework, you sometimes face difficulties that in other situations, specifically while learning a new language or framework would not even challenge you.
One example for such a case is one I’ve encountered this past week, and to tackle it, all I’ve needed to do is to actually read the Drupal docs and not just flip through it.
One of my clients came to me and told me that all of the images he’s uploading to his site are deleted from the files directory of his Drupal project after several hours.
After checking that the images are created successfully in the Drupal’s temp directory and are then moved to the files directory as they should, I begun checking for any file/image related modules and any Drupal configurations that could hint a relation to the problem.
Checking those off I’ve started to look at custom code developed by our programmers, as this is a more time-consuming task I’ve not started with it but knew from the beginning that this is probably where the culprit could be found.
While carefully combing the code I’ve landed upon a form api piece of code related to an image field similar to this:

<!--?php
// Use the #managed_file FAPI element to upload an image file.
$form['image_example_image_fid'] = array(
  '#title' => t('Image'),
  '#type' => 'managed_file',
  '#description' => t('The uploaded image will be displayed on this page using the image style chosen below.'),
  '#default_value' => variable_get('image_example_image_fid', ''),
  '#upload_location' => 'public://image_example_images/',
);
?>

This piece of code will add a nice file/image field to the page and will allow you to attach an image to the current entity.
After finding the “managed_file” type documentation the problem and the solution was clear.

Note: New files are uploaded with a status of 0 and are treated as temporary files which are removed after 6 hours via cron. Your module is responsible for changing the $file objects status to FILE_STATUS_PERMANENT and saving the new status to the database. Something like the following within your submit handler should do the trick.

 <!--?php
 // Load the file via file.fid.
 $file = file_load($form_state['values']['my_file_field']);
 // Change status to permanent.
 $file->status = FILE_STATUS_PERMANENT;
 // Save.
 file_save($file);
 // Record that the module (in this example, user module) is using the file. 
 file_usage_add($file, 'user', 'user', $account->uid); 
?>

So in order to prevent the (weird – in my opinion) automatic 6 hour cron deletion of the uploaded images you have to add a submit handler and inside it add that piece of code.
To clarify and help those in need, this is an expanded example of a form and submit functions.

$form = drupal_get_form('my_module_example_form');
...
function my_module_example_form($form, &$form_state) {
  $form['image_example_image_fid'] = array(
    '#title' => t('Image'),
    '#type' => 'managed_file',
    '#description' => t('The uploaded image will be displayed on this page using the image style chosen below.'),
    '#default_value' => variable_get('image_example_image_fid', ''),
    '#upload_location' => 'public://image_example_images/',
  );

    $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Submit'),
  );
  return $form;
}
function my_module_example_form_validate($form, &$form_state) {
  }
function my_module_example_form_submit($form, &$form_state) {
  }

Originally posted on my personal blog.

Jun 05 2014
Jun 05

It's a bird - It's a plane - No! It's AnguDrop

Angularjs and Drupal - A new power couple in the open web space.

Angularjs is a refreshing javascript framework created and promoted by Google and is one of those open source projects (like Drupal) where you simply know will be around for the next 4-5 years and are about to leave a dent in the open web space. Angular is one of the prime members of our new M.E.A.N framework which contemplates Drupal for high performance mobile backends and more challanging startups - Get some Angular.js help now from our resident Ninjas :). The beauty in Angular (as in most javascript MVC frameworks) is how it organizes the different parts of the application (views, controllers, services..) and enforces it's opinionated view of how things work and why. This lets you build complex single page applications in a predictable and standardized way. It also presents an interesting approach on how to address some of the more common customer scenarios..

A refreshing coke in Drupal Hell

We have seen many customers that are stuck in some kind of Drupal Hell with codebase from Drupal 5 stuck in time because their original developer hacked core or views and they never had the budget to upgrade. It's extremely challenging to provide value to this type of customer but we've found an interesting pattern using Angularjs to create modern cutting edge interfaces even within the weirdest sphagetticoded nightmares. So let's say we have a Drupal5 site stuck in 2008...

  • Create a content type called angularapp
  • Overide page.tpl.php as page-node-angularapp.tpl.php (Drupal 5 needed custom code in template.php
  • Load the angular.js library and dependencies plus your apps code
  • Comment out the print of the $content in you're overiden template and instead add
  • The code above renders the angular app based on the code

The idea is to replace the rendering of $content all together when the angularjs is rendered.

Is there anybody out there?

It doesn't matter how much amount of frontend wizardry goes on we still need someone to answer those angular services and provide the frontend with the data coming from the Drupal site. We do a fair amount of node.js server side programming so sometimes drupal isn't even part of the equation but when Drupal is the server side there are several options to address it. * 1. [Services module](http://drupal.org/project/services) (Drupal - 5-8) 2. [restws module](http://drupal.org/project/restws) (Drupal 7) 3. As Will Vincent pointed out you can roll your own with returning drupal_json_output in your hook_menu. For the Angular curious - I created a gist (rendered belowe) - walking through the relevant steps in an angular app - https://gist.github.com/liorkesos/5528234

Mar 06 2014
Mar 06

Maybe it's just me.. But I see more and more DG's (Drupal Geezers) find themselves introspecting and thinking about the technology they have invested their past 7-8 years in.

The web is exploding with tons of amazing javascript mvc platforms, crazy socket madness and stunning widgetry all running client-side (in the browser) with amazing sub-second speeds.

Our reality is that we still live in a world where 10% of the functions we use frequently in drupal end with .+_alter - Drupal typically will output whatever markup you want and then you find yourself wrestling with it and altering it to fit the semantic html you want. To actually get Drupal to come close to sub-second performance means to wrap it with so many caches it looks like an Egyptian mummy.

Unthemeing

The main challenge I see with Drupal revolves around theming, because Drupal is a great CMS for beginners it bundles every layer of markup possible so it can be tweakable from the admin UI, but in the process if you want clean, simple semantic markup of blocks, menus, views, panels etc... - you really need to know what you're doing. Thus you see more and more Drupal shops experiment with decoupling the front and back side of Drupal. Drupal is awesome in managing content, users, groups and processes but when it renders that information it's sometimes heavy, bloated and inflexible. The way we approach this is through building the interface with angular.js an awesome MVC javascript framework and connecting through web services to the Drupal containing the data. In the past 2 years we have started to experiment with technologies augmenting Drupal - building apis powered by node.js and mongoDB for scalable mobile endpoints, and building angularjs based widgets that we've inserted in to existing Drupal sites. I talked about this in a webinar by acquia 2 years ago but as we reimplemented these fullstack javascript implementations we felt we needed to standardise around a common solution for our internal needs.

Mean.io

We've merged all of the best practices for fullstack javascript development within the mean.io project. MEAN is an acronym coined by Valery Koltarov from MongoDB and is used to describe applications built by MongoDB, Express, Angular.js and Node.js. We and over 3200 developers which stared the project in github are awed in the speed and quality that comes when you're actual building what you need and not constantly altering what you got from Drupal. So we have this awesome js framework that knows how to serve content very well but lacks a CMS, and we have a CMS (that we still love) which does an awesome job of managing content but can do a better job serving it. We combined both worlds with the mean module providing a standard way to bi-directionly communicate between mean.io instances and Drupal.

The mean module

Although Drupal 8 is coming up there are tons of Drupal 6 sites out there that want to spice up the look and feel yet maintain the content, ccks and views involved. We thought how to expose the data within drupal to rich widgets or single page applications which either feed information in to drupal or use information fro within to provide a dynamic experience. The mean module (at http://drupal.org/project/mean) provides the means to export blocks,menus views and variables to one big json file which is accessed by an angular.js service which reads it and makes it available to the mean application.

Integration Strategies

There are two types of patterns that can be implemented using the mean module.

Mean in front

mean.io is used in many places as an engine for SPA (single page applications) now we can create applications that are built from information which is held in drupal. Mean provides an interface to load various pieces of data from a Drupal sites and to render a single-page application which uses Drupal as an additional data source. We implemented this approach lately with Strauss an established enterprise customer which had an OpenIdeal - Drupal 6 site which they wanted to face lift. You can browse here to see the result and here to peek in to the drupal in the backend which powers it.

After enabling the mean module you can browse /mean/json/help/me and see the following possabilities...

URL stucture: /mean/json/[TYPE]/[NAME]/[ARG1]/[ARG2]/[ARG3]
currently supported TYPE values and their arguments:
- view - returns results for requested Drupal view object, arguments:
  - NAME - view's name
  - ARG1 - (optional) display_name
  - ARG2 - (optional) items per page value (-1 for unlimited, 0 - skip arg)
  - ARG3 - (optional) arguments divided by '+' sign without whitespaces
- menu - output from menu_tree_all_data() function
- load - looks for load_[NAME_mandatory] function and returns its output
(node_load([ARG1]), user_load([ARG1]), menu_load([ARG1]) ...), arguments:
  - ARG1 - ID or name to pass to load function
- help - /mean/json/help/me will output current instruction
- user - /mean/json/user/logout - Logging current user out
  - /mean/json/user/login (along with name and pass values passed as post
  will log user in and return its object)
  - /mean/json/user/session - returns $_SESSION
  - /mean/json/user/me - returns global user object
- get-mean-packet
  - returns set of JSON objects, set at admin/build/mean-packets
  - NAME - packet's name
-------------------------------------------------------------------------
To skip any optional ARG, use 0, (example: /mean/json/forum_search/0/5)

Angular apps in blocks/panel panes

In many cases we have to continue hosting with Drupal - for instance if you have a governmental site that has been security cleared to run Drupal there is a very slim chance you could change that. With the next approach you can still get the "single page" behaviour or implement a complex widget that you'd rather implement on a client-side MVC rather then in a bunch of spaghetti code in jquery.

We have been working with a financial client from new-york for the past year which has a huge antiquated drupal-5 site and the ability to insert rich angular.js driven application that connect to the data within the drupal site - can create a modern feel even if you're stuck in the past, it also can provide a clear path to fix sites that can't be upgraded because their core has been altered.

Drush support

One of the concepts and tools we've built to help with both types of integrations - has to do in how to swiftly enter the Drupal data in to a mongodb based db so it can be served effectively to mobile devices, widgets and single page applications. We have bundled the mean shadow module with the the mean module which provides a standard way to sending drupal information upon content update to the Mongo/Node based service. To make the initial import of the data in to the mean easy we provide the drupal shanties (shadow entities) command...

Here are some examples of the possible usage..

Examples:
 Standard example (all the user entities)  drush shadow-entities              
 Type example (all the node entities)      drush shadow-entities node         
 Id example (specific user)                drush shadow-entities user 42      
 Id example 2 (specific node)              drush shadow-entities node 42      
 Bundle example (all the entites of        drush shadow-entities node article 
 bundle article)                                                              

To summarize - mean.io is an amazing way to develop cool and modern applications but the mean module integration lets us start building mean apps now and helps them co-exist and augment Drupal.

Feb 12 2014
Feb 12

After working many years with a specific framework, you sometimes face difficulties that in other situations, specifically while learning a new language or framework would not even challenge you.
One example for such a case is one I’ve encountered this past week, and to tackle it, all I’ve needed to do is to actually read the Drupal docs and not just flip through it.
One of my clients came to me and told me that all of the images he’s uploading to his site are deleted from the files directory of his Drupal project after several hours.
After checking that the images are created successfully in the Drupal’s temp directory and are then moved to the files directory as they should, I begun checking for any file/image related modules and any Drupal configurations that could hint a relation to the problem.
Checking those off I’ve started to look at custom code developed by our programmers, as this is a more time-consuming task I’ve not started with it but knew from the beginning that this is probably where the culprit could be found.
While carefully combing the code I’ve landed upon a form api piece of code related to an image field similar to this:

<!--?php
// Use the #managed_file FAPI element to upload an image file.
$form['image_example_image_fid'] = array(
  '#title' => t('Image'),
  '#type' => 'managed_file',
  '#description' => t('The uploaded image will be displayed on this page using the image style chosen below.'),
  '#default_value' => variable_get('image_example_image_fid', ''),
  '#upload_location' => 'public://image_example_images/',
);
?>

This piece of code will add a nice file/image field to the page and will allow you to attach an image to the current entity.
After finding the “managed_file” type documentation the problem and the solution was clear.

Note: New files are uploaded with a status of 0 and are treated as temporary files which are removed after 6 hours via cron. Your module is responsible for changing the $file objects status to FILE_STATUS_PERMANENT and saving the new status to the database. Something like the following within your submit handler should do the trick.

 <!--?php
 // Load the file via file.fid.
 $file = file_load($form_state['values']['my_file_field']);
 // Change status to permanent.
 $file->status = FILE_STATUS_PERMANENT;
 // Save.
 file_save($file);
 // Record that the module (in this example, user module) is using the file. 
 file_usage_add($file, 'user', 'user', $account->uid); 
?>

So in order to prevent the (weird – in my opinion) automatic 6 hour cron deletion of the uploaded images you have to add a submit handler and inside it add that piece of code.
To clarify and help those in need, this is an expanded example of a form and submit functions.

$form = drupal_get_form('my_module_example_form');
...
function my_module_example_form($form, &$form_state) {
  $form['image_example_image_fid'] = array(
    '#title' => t('Image'),
    '#type' => 'managed_file',
    '#description' => t('The uploaded image will be displayed on this page using the image style chosen below.'),
    '#default_value' => variable_get('image_example_image_fid', ''),
    '#upload_location' => 'public://image_example_images/',
  );

    $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Submit'),
  );
  return $form;
}
function my_module_example_form_validate($form, &$form_state) {
  }
function my_module_example_form_submit($form, &$form_state) {
  }

Originally posted on my personal blog.

May 06 2013
May 06
angularjs drupal

It's a bird - It's a plane - No! It's AnguDrop

Angularjs and Drupal - A new power couple in the open web space.

Angularjs is a refreshing javascript framework created and promoted by Google and is one of those open source projects (like Drupal) where you simply know will be around for the next 4-5 years and are about to leave a dent in the open web space. Angular is one of the prime members of our new M.E.A.N framework which contemplates Drupal for high performance mobile backends and more challanging startups - Get some Angular.js help now from our resident Ninjas :). The beauty in Angular (as in most javascript MVC frameworks) is how it organizes the different parts of the application (views, controllers, services..) and enforces it's opinionated view of how things work and why. This lets you build complex single page applications in a predictable and standardized way. It also presents an interesting approach on how to address some of the more common customer scenarios..

A refreshing coke in Drupal Hell

We have seen many customers that are stuck in some kind of Drupal Hell with codebase from Drupal 5 stuck in time because their original developer hacked core or views and they never had the budget to upgrade. It's extremely challenging to provide value to this type of customer but we've found an interesting pattern using Angularjs to create modern cutting edge interfaces even within the weirdest sphagetticoded nightmares. So let's say we have a Drupal5 site stuck in 2008...

  • Create a content type called angularapp
  • Overide page.tpl.php as page-node-angularapp.tpl.php (Drupal 5 needed custom code in template.php
  • Load the angular.js library and dependencies plus your apps code
  • Comment out the print of the $content in you're overiden template and instead add
  • The code above renders the angular app based on the code

The idea is to replace the rendering of $content all together when the angularjs is rendered.

Is there anybody out there?

It doesn't matter how much amount of frontend wizardry goes on we still need someone to answer those angular services and provide the frontend with the data coming from the Drupal site. We do a fair amount of node.js server side programming so sometimes drupal isn't even part of the equation but when Drupal is the server side there are several options to address it. * 1. [Services module](http://drupal.org/project/services) (Drupal - 5-8) 2. [restws module](http://drupal.org/project/restws) (Drupal 7) 3. As Will Vincent pointed out you can roll your own with returning drupal_json_output in your hook_menu. For the Angular curious - I created a gist (rendered belowe) - walking through the relevant steps in an angular app - https://gist.github.com/liorkesos/5528234

Sep 24 2012
Sep 24

As the temperatures here in Israel start changing to something sane and in the peak of the holiday season... I want to re invite whomever is the mideast (that's the world's middle east not Ohio :) ) to Drupalcamp Israel. Attendence is almost fully booked due to a high signup (around 170 people payed) and another big group of 60 Drupal newbies sponsered by the local internet association. We have awesome speakers like Minister Michael Eitan that has been championing Drupal in the Government, Amitai Burstein from Gizra (an ex linnovatee) and Tsachi, Zohar, Yuval, Yaniv and myself giving lectures. Jeffery (JAM) Macguire from Acquia will fill in the slot for that lecture you can actually understand if you don't speak hebrew, yet if you have spent some time in jewish school or just want to listen to a funky language with scattered "views", "commerce" , "context" and more you're more then invited :) ). Google, ISOC,Incapsula (real cool Israeli startup), Raid are sponsoring the event and by the level of the lectures and engagement of the local community - I think it'll be a blast. So... If you are in the neighberhood - be sure to drop by to http://2012.drupal.org.il/ (warning hebrew!) and join us for the fun!

Aug 26 2012
Aug 26

[Under.me](Under.me) is one of our most beautiful websites, and a lovely demonstration of how [Drupal Commernce](http://www.drupalcommerce.org/) can look and behave. We're happy to have published a featured case study on drupal.org. So read about [Under.me - Under the Hood](http://drupal.org/node/1726722).

Aug 26 2012
Aug 26

Drupalgive is a new and effective way of showing your love and contributions to [Drupal](http://www.linnovate.net/services#service-417). It is an initiative by the one and only [Moshe Weitzman](http://drupal.org/user/23), which defines a special page on your website, where you can gather in one place all of your contributions to Drupal: modules, themes, events you've sponsored, presentations you've made... everything which is contributing to the development of the Drupal project, in it's whole. In the last days, towards Drupalcon Munich, we've seen a growing number of Drupal shops adding and [talking](http://www.agileapproach.com/blog-entry/drupallove) about their Drupalgive pages. To mention a few: [Phase2](http://www.phase2technology.com/drupalgive), [Mediacurrent](http://www.mediacurrent.com/drupal-give), [DataFlow](http://www.dataflow.be/nl/drupalgive), [Inclined](http://www.inclind.com/drupalgive) and others, who join [Acquia](http://www.acquia.com/drupalgive), [Chapter Three](http://www.chapterthree.com/drupalgive), [Zivtech](http://www.zivtech.com/drupalgive), [Linnovate](http://www.linnovate.net/drupalgive) and many more. Drupalgive pages are eventually contributing to Drupal shops and freelancers, by showing to the world just how great of a community member you are. And as you know, in Open Source world code is gold, and gold sponsorships are not less important :) **So show your contributions, and see how your Karma grows a little!** Follow [@Drupalgive](https://twitter.com/drupalgive) to learn about new contributions and read more about the [initiative](http://drupal.org) on drupal.org and on it's [Drupalgive Planet](http://drupal.org/planet/drupalgive). Feel free to leave your /drupalgive URL a comment. (BTW, I know the logo sucks, I made it myself :) If you feel like sending me an alternative, I'll be gracious!)

Jul 18 2012
Jul 18

There was a lot happening on the dev branch lately and now time have come to release all this work to the wild in the form of a 7.x-2.5 release. I thought I should do a quick review of what happened since 2.4 so you won't miss anything, here it is - Clear cache now recompile Sass alt+c clears caches File watcher now supports

tags Debugging - force recompile Compass URL helpers Image sprites generator ### Clear cache If you have dev mode turned on, your Sass files are recompiled whenever they change, and can even update your browser if you use the file watcher, but on production, with dev mode off and CSS aggregation turned on, you had to go to theme settings, recompile your Sass files and then flush your CSS cache to get the changes. That was an issue that bugged me from day one. not anymore. Now you can simply clear your cache to recompile all of your style sheets and **regenerate all of your image sprites** (yeah, I'll get to that). ### alt+c clears caches If we're clearing cache, let's do it with style alt+c. As simple as that, keyboard shortcuts are faster and time is money, so if you find yourself looking for that admin-menu "flush cache" link every once in a while just use alt+c. This assumes you have admin-menu installed (to provide the hook_menu), on the latest version of admin menu alt+c will clear your CSS and Javascript cache (instead of all caches), which is a much faster way to force recompilation of Sass files. ### File watcher now supports

tags Sasson's file watcher (you know, the script that updates your browser whenever you save a style sheet without refreshing the page) was assuming your style sheets were all called as @imports which is usually true with Drupal 7, but not always. Now it will look for style sheets called as

tags too. ### Debugging - force recompile On older versions of Sasson, dev mode would recompile your style sheets on every page request, that actually didn't took that long, but it made no sense. so on one of the later versions we made it so that Sass files will recompile only when they change. but then we thought that on some occasions, probably for syntax debugging, you might actually want them to recompile over and over. Now you have a check-box on your theme settings page under the "SASS / SCSS settings" tab to force recompilation of your Sass files, image sprites too. As a side note, I have also removed the check box to force rebuilding of theme registry, who does that anyway ? ### Compass URL helpers You know Compass URL helpers ? if you don't, you should, because now Sasson supports those too. Basically they allow you to define an images (or fonts, or stylesheets) directory, and reference it in your Sass using image-url('filename') so you have something like: body { background: image-url('body-bg.png') repeat-x 0 0 #fff; } By default, those functions will point to the /images, /styles and /fonts directories under the root of your theme, but you can set a different path on your theme settings page under the "SASS / SCSS settings" tab. This useful feature can be used for example to easily move you images to a different (CDN) server when moving the site to production or for simply restructuring your theme's directory. ### Image sprites generator Image sprites are important, they really are, they minimize http requests and save time both for our users and for our servers. the problem with them is maintenance. It is very hard and time consuming to manually build efficient sprites and it is even harder to maintain them when a project grows. I have always wanted a simple tool that will let me use my images and seamlessly build me sprites in the back-end. Now lately Compass for ruby can do that, but our version of compass couldn't, that's a shame, we should fix this. so we did. Sasson now includes an image sprite generator. it will build the image for you, and will calculate all the background positions for you. you only need to know the image file name. This is how it works - Under your sub-theme's /images directory you will find a /horz, /vert and /smart directory. The images in the /horz directory will compile into a horizontal sprite (e.g. for vertically repeating backgrounds). The /vert directory will produce a vertical sprite. The /smart directory will produce an image sprite that will position all the images on the smallest area possible. You can create as many sprites (directories) as you like, as long as the directory names have horz/vert/smart in them (e.g. smart2). After you have your images in a directory, in you .scss file, you may do something like that: @import "sprites/DIRECTORYNAME"; This will generate an image sprite out of your the images in the DIRECTORYNAME directory, after you have created your sprite, you can use it by simply: @include sprite-DIRECTORYNAME-IMAGENAME; So in the end you get something like: @import "sprites/smart"; .selector { @include sprite-smart-icon; } **See that ? no more background position ! you can even add more images to the sprite, regenerate a whole new sprite, background positions change completely, you couldn't care less.** Now that's not all. by default you will get the background image, position, and the specified selector will also get the width and height of the original image. If you also want the selector's text to hide (the so called - CSS Image Replacement technique) you can simply pass a true argument to the @include, like so: .selector { @include sprite-smart-icon(true); } If you don't want the width and hight set on the selector you can pass a second false argument: .selector { @include sprite-smart-icon(false, false); } This will only give you the background image and position. Oh, last thing, Sassons demo site is up again, needs work, but still... Anyway, as you can see, Sasson v2.5 is pretty exciting, don't you think ? Try the new Sasson. and please share your experience.

Download Sasson

Apr 02 2012
Apr 02

A video communication area, arranged in several views: A students’ portfolio accordion: And a very complicated courses search mechanism - the subject of this post: Background / What we’re working with here Since John Bryce is all about training, the heart of their site’s content is obviously *courses*: There are courses, and for each course, there’s optional information, related to a specific instance of that course. That way, if a course has several opening times, we only store most of its info once, and keep per-instance related info, which we get from a web-service, separately. The Drupal structure for our courses is this: The courses themselves, implemented as 2 slightly-different content types, hold information such as the name of the course, an introduction, body text (in tabs), and various informative fields and taxonomies. The optional info, which we call “course instances”, contains mainly an opening date, the location where the course is given, how long the course is, and whether it’s a day or an evening course. The really tricky bit, which we’ll discuss here, was creating the search mechanism, which needs to search and filter in both the courses and their instances. Keep in mind, though, that we might want to find a course containing a certain text, but which also starts next month - and none of our content types hold both of these bits of information. So the challenge is: searching content for information it doesn’t actually have. First step / Indexing In order to find what you’re searching for - it’s got to be there! That’s why we interfere in apache solr’s indexing process using hook_apachesolr_update_index(). When indexing, we check each node’s type. If it’s of type *course* or *course instance*, we generate some fields for it. When dealing with course instances, there’s almost nothing there, as far as content goes. So we load the course that this course instance relates to, and copy the info off it. We append the fields that should be search-able through the free-text search (like the course’s body and introduction) to solr’s index main body field, like so: $document->body .= $field_content_from_the_course Taxonomy field values get added as separate index fields (which we make up), like so: $document->addField($field_key, $field_value); type == 'course_instance') { //Adding short_introduction field $intro = $course_node->field_short_introduction[0]['value']; $document->body .= $intro; } } ?> Now the course instances have all of the courses’ content. But we still need to treat courses: Apache solr indexes taxonomy term names by default. We wanted term ids, which is also what we indexed for the course instances. So we repeat some of the above process for nodes of type course - the parts that relate to taxonomy. And, voila! Indexing is done. Second Step / Modifying the Query To actually use our search mechanism, our next logical step is creating a custom advanced search form, which we meddle with on submit, to get everything nicely to the URL’s querystring: For example, we want to allow users to search for courses in several categories at once. The default is to use the “AND” operator, but we want “OR”, because each course only belongs to one category. So in the form’s submit function, we have: implode(" OR ", array_filter($form_state['values']['sections'])) which gives us a nice OR filter in the querystring. To help apache solr use all those carefully crafted filters from the URL, we use hook_apachesolr_modify_query(), and add the relevant filters to solr’s query, like so: $query->add_filter("field_name", $value_from_get, FALSE) add_filter("ss_tra_section", $filter, FALSE); } } } ?> Now apache solr should know how to deal with all the info our user wanted to send it. Third Step / Reducing Duplicates So we run cron, and everything is indexed, and using apachesolr_views, we even get results, BUT - now we get multiple results for many of the courses, because we get both the course and its instances. What to do? Using hook_views_post_render(), we grab the results of the search from the view, loop through them, and insert the nid from each result into an array. Since we have so-called duplicates, this array will have duplicate values. Using array_unique(), we end up with a unique-valued array, which we now explode with plus(+) signs and stick into a variable. To display these results, we call a different view we’ve prepared beforehand, and give it the variable, using views_embed_view(). name == 'jb_search' && $view->current_display == 'page_1') { if (empty($view->result)) { variable_set('jb_uniques_search_results', NULL); $output .= $view->empty['option']['content']; } else { foreach ($view->result as $result) { if ($result->type == 'course_instance') { $uniques[] = $result->node_data_field_course_field_course_nid; } elseif ($result->type == 'professional_course' || $result->type == 'training_course') { $uniques[] = $result->nid; } } //Get a unique element array from the nodereference course field. $uniques = array_unique($uniques); $uniques = implode("+", $uniques); //Set a string of the unique elements glue with "+" as an arguments for the //"course_by_arg" view. See jb_solr_search_courses_block(). variable_set('jb_uniques_search_results', $uniques); //hide the original "jb_search" result output. $output = ''; } } } ?> In the last line, $output = ""; we hide the original view, which we don't want to display, because we'll be showing the new view. No more duplicates! Fourth Step / Facets Apache solr makes facets out of the box, but since we’ve created custom index fields, we now have to tell solr to make facets for them:

  1. First things first, declare your facets to the world: Using hook_apachesolr_facets(), we declare a facet, using the exact name of the field we created when we did the custom indexing. t('facet: By Category'), 'facet_field' => 'ss_category', ); // …more of the same return $facets; } ?> This adds the facets to the "enabled filters" page: admin/settings/apachesolr/enabled-filters, where we need to:
  2. Enable the newly-born facets at the above link. After we enable the facets, Drupal tells us to go to the blocks page and place the new facet blocks in some region. We actually prefer context, so we add the blocks there. Oh, and to have the blocks actually appear on the page, in hook_block’s view part, we use apachesolr_facet_block to print the block to the page.
  3. Create some arguments for views: For views to be able to deal with the new facets, we need to declare arguments for them. In hook_views_data_alter(), we add a section for each new index field, using apachesolr_views_handler_argument as the handler. This done, we add the argument in the view, and now it can filter on our new facets.

Sounds easy, right? Well, not really, but here’s a little tip to make it easier for you: You can shorten the 2 minute delay in processing the indexed data if you edit the value for maxtime in the example/solr/conf/solrconfig.xml file. Happy searching!

Apr 01 2012
Apr 01

Under.me is probably THE sexiest Drupal website around, both for it's amazing front-end technology and UI, as well as for it's so-good-looking models: David Balsar and Bar Refaeli, the world famous top-model.
Under.me is the online store for their new brand of underwear, designed and demonstrated by Bar Refaeli.

It is a state-of-the-art website, with the latest best practices in Drupal and Front-End development. Using Sasson, an HTML5-CSS3-SASS Drupal theme, and a lot of jquery magics, dictated by the fine UI/UX work by Eyal Shahar, we are able to deliver a new and unique experience of online shopping. Within a couple of clicks, the visitor is able to browse the catalog and add product to the cart.

Under.me is a light-weight one-page catalog, which aims to create the most pleasant shopping experience, with as little fuss as possible - easily add and remove items to the cart, and never lose focus. Bar's presence in every step of the purchase process is communicating credibility blended with fun and fresh spirit.

To make it even easier for returning customers, Under.me offers a unique concept of subscriptions to packages, so one can periodically receive new items, without te need to go back to the online-shop and re-execute the same purchase - this is perfect for anyone who likes their shopping experience to be as comfortable and fit as their underwear clothing is :)

Mar 02 2012
Mar 02

_**Update** - The CSS Flipper now lives in a separate module and won't be included in Sasson v3.x - this means practically any theme can be flipped in no-time (use the spare time to contribute it back to the community :) )._ Long story short, Sasson can RTL itself with a single line of code. Long time ago, when we wanted to add bi-directionality to our site for RTL (Right-To-Left) languages like Arabic or Hebrew we had to use tools like CSSJanus or RTLer to flip our CSS and then paste the result into style-rtl.css and fix whatever needed fixing. This workflow have several drawbacks: * It isn't fun. * It is a maintenance burden - you must manually update your style-rtl.css with every change to style.css * Those auto RTL tools will never handle sass/scss files. * After auto-RTLing, your RTL css isn't ready yet, you usually still need to adjust it (e.g. remove the not RTLed lines) * Many auto-RTLers can't handle media queries. Sasson takes care of all this, and with a single line of code. This is what you do: * Put all your styles into style.**s**css (plain css is so 2010) * Create style-rtl.scss next to style.scss * Put this line in style-rtl.scss @flip {file: "style.scss"}; * Check your site and add any fixes after this line (e.g. use different background-images). ### Some examples What Sasson does is take this @flip line and replace it with a flipped version of the named style sheet, that means that - #logo { float: left; } in the CSS output becomes - #logo { float: right; } But this is just the beginning, what most auto-RTLers fail to do is remove unRTLed lines, in drupal we put only the overrides in our style-rtl.css file since both style.css and style-rtl.css are called on RTL pages, but with sasson - .class { padding: 1px 2px 3px 4px; margin-right: 3em; background: url(image.gif) no-repeat right center; margin-bottom: 20px; color: #222; } Will become - .class { padding: 1px 4px 3px 2px; margin-left: 3em; margin-right: auto; background: url(image.gif) no-repeat left center; } Notice how Sasson adds the margin-right: auto; to reset the right margin, and how it removes the lines that don't have any directionality overrides in them (e.g. the color property) thus keeping the CSS output as light as possible. Keep in mind that since this file is being recompiled when needed, every change to style.scss will be automagically imported and flipped in style-rtl.scss ! ###Bottom line Sasson can turn THIS into THIS and all you have to do is THIS. And that's not all... ### With Sasson you can go the other way around too ! Drupal allows you to have your RTL overrides in style-rtl.css but what if you develop an RTL site and only want to put some overrides for a small english (LTR) section ? With Sasson you can go both ways, that means you can have your default styles in style.css (they can be either RTL or LTR) and put your LTR overrides inside style-ltr.css, this file will be called on LTR pages only. So basically you can have style.css that loads on every page, style-rtl.css that loads on RTL pages only and style-ltr.css that will be called only for LTR pages.

Feb 09 2012
Feb 09
Following this great article from Howard Tyson @Zivtech, I felt I must demonstrate how easy it would be to build the exact same responsive grid with Sasson. What we're doing is configuring a responsive layout based on 960 grid system using Sass, that means that instead of applying the grid classes to our markup, we're applying them to our element IDs thus keeping a clean and semantic markup and separating content from style. Now, enough with the geek talk and let's see how simple that is. Basically all you need to do is to set the desired values in this form: Sasson's grid settings And if you want to set different break points you may configure them on this tab: Sasson's responsive settings So with this minimal effort we have set a grid based layout which is responsive and will adapt to the device it is viewed on. As a matter of fact, even this little effort is optional. in case the default values that ship with Sasson suites your needs, all you have to do is download and enable it, done. So why use a base theme ? because it does all this for you, because you don't want to do this again and again every time you start a project, because it keeps you up-to-date with latest technologies and sometimes it can even teach you a thing or two. Happy sub-theming :)
Jan 30 2012
Jan 30
Sasson means "Joy". This drupal theme is all about bringing the joy back into drupal theming by making your work effective and smart, and your results professional and faster, faster for you to develop and faster for the end-user to browse. Clean and simple code, lightweight structure, latest technologies, 100% open-source and the best DX (developer experience) we could think of is what we hope you will find in this new drupal base theme. We'll quickly go over most of the main features of Sasson and see how to use them. Sasson - using sass for smart drupal theming

Sass compiler - built in !

Sass makes CSS fun again. Sass is a meta-language on top of CSS that’s used to describe the style of a document cleanly and structurally, with more power than flat CSS allows. Sass both provides a simpler, more elegant syntax for CSS and implements various features that are useful for creating manageable stylesheets.

Explaining what you can do with sass is way out of the scope of this blog post but let me just say it's awesome, to see how awesome it is you can check out its homepage. Sasson gets its power mostly from the use of sass, it allows us to do math and use mixins, this way we can do amazing stuff:
  • Create any grid you can imagine, without those nasty classes cluttering the markup, it is responsive and to top it all, it is configurable from your theme settings, but we'll get to it later.
  • Never use css vendor-prefixes again, just write border-radius, box-shadow, transition etc. vendor specific prefixes will be added for you. see hook_prefixes_alter() if you want to add more.
  • Pass variables from the theme settings form or any other php script and into the sass compiler, you can do this in your sub-theme as well, see hook_sasson_alter().
  • Use variables, nesting, mixins, selector inheritance, if-else statements and much more.
Sasson uses PHamlP to compile sass to CSS so there are no prior requirements, just install it and start writing sass. Compass is one of the things that makes sass so much more powerful then other CSS preprocessors, it is also included so you can enjoy this huge library of mixins and functions as well to make your CSS even smarter. In your theme settings, under 'SASS / SCSS settings' you can turn on/off Sasson's 'Development mode' when this is on, sass files will be recompiled on every page load and FireSass support is enabled. When not developing, turn development mode off, this will keep your CSS output light as a feather, in fact, the output of our semantic version of 960gs is much slimmer then the original CSS grid system. tip: sass/scss files are compiled to CSS files with the same name, that means that if you want to override a parent-theme's sass/scss file from your sub-theme, you can simply create a sass/scss file with the same name and it will override the original one, but remember this - when manually creating multiple sub-themes, you should avoid having two sass/scss files with the same name because they will override each other, if using drush sns to create sub-theme we take care of that for you. Sasson - using sass for smart drupal theming

Mobile friendly - adapt to the browser

Everybody talks about how desktops are out and mobile devices are in, big time. designing a layout that will adapt to all these different screens is now more important then ever, Sasson gives you a responsive layout, which is completely configurable from your theme settings, under 'Responsive Layout Settings' you can choose the breakpoints in which your page will switch from one layout to another. Many developers believe we should design for mobile devices first and progressively enhance the UI according to the device being used (e.g. serve small background image for mobile and bigger if the device/browser is bigger), on the other hand, many designers prefer to design for desktops and only do some adjustments if a mobile design is being used. Sasson even lets you choose between a mobile-first or desktop-first approach, again, right from your theme settings. On very small devices, you would like your horizontal menus to become a drop-down
Dec 20 2011
Dec 20
While Features module is one of the main building stone of any Drupal website today, it has some aspects which can drive you (and/or your client) mad. One of it's bigest problems is that it creates a very strong link between the feature and the configuration of the website. You may say: > "Hey! that's the whole idea of Features!" Yes, that's right, but only as far as transferring configuration between different environments of the website (the famous **Dev > Staging > Production** path). Once a feature is installed on a production server, and the website operates as advertised, the client may want to start modifying it. The most evident example is adding menu items and changing labels in views. The client just got a super duper CMS and they certainly have the right and ability to modify such elements on their website. However, once they touch anything which resides in a feature, they break the holy path described above. If the development of the website is done and over, nothing bad happens. However, if the development continues, the developers will find themselves rather limited, as they will have to download an updated feature **each time before they touch the code**. This can be a tedious task if the websites undergoes continuous development, and the client is constantly modifying and adjusting their website (this is also true for the last phase of the development, even before going live). The intuitive solution for the unexperienced developer, would be to simple remove the relevant components from the feature. **Ha ha!** When you remove an element from a feature, this element is removed from the site completely, and is not getting pushed back to the DB. There go lots of efforts done by the furious client, and the frustrated dev now needs to dig in backups and code to understand what went wrong... > "Hey! that's the whole idea of FTools!" Yep! Our new Features Tools (FTools) adds a "**Safe Un-Link Feature Element**" functionality to the recreate feature form. By doing so, a copy of the detached element is kept as a file, just like feature saves configuration in files, and the modified configuration does not gets lost. The following video will teach you how to use the FTools to auto create a feature, and to safely unlink elements from a feature without loosing any data. [embedded content]
Nov 23 2011
Nov 23

Drupal apps are the latest hype in the Drupal community, and Drupal app stores will be next. Linnovate has taken the task of developing the first generation of app stores for Drupal. This article covers one of the fundamental dilemmas with regards to app stores: How is it at all possible?!

Apps come to solve the problem of expanding a Drupal site with new features, and doing it easily. Phase2 and LevelTen have both good presentations of the general idea. Our goal is to leverage the existing state of the art to the next level - serving any Drupal website, regardless of it’s code base (usually distros).

When speaking of Drupal app stores, we have three kinds of implementations, presented hereby. As a store operator or as a provider of apps, these three kinds stand for three levels of comprehension of the destination platform (the client end).

  • Hosted solutions (cloud based products): E.g., Drupal Gardens, SubHub.
    In a cloud, both the store and the client are in reach of the cloud providers and they have full comprehension of the client platform. The store and the client can share the same server and the same user authentication. Moreover, the operators have an exact image of the client’s capabilities and installed software.
  • Drupal distributions: E.g., Open public, OpenideaL, Open Enterprise, Open* .
    When the the client is based on a distribution, there are some assumptions we can count on, or at least take under consideration. We can have a pretty good guess about which contrib modules are installed. However, our comprehension is not complete, since the client may have changed some of the original parts, and added/removed software. The apps.module was made just for that and does a good job.
  • Custom Drupal sites: E.g.... your website!
    Last comes the custom Drupal website. Basically we can count on Drupal’s minimal installation profile and the appstore_client.module to be installed. We have close to zero comprehension of the environment. Absolute darkness. Spooky...

When implementing the Appstore model, we targeted all the above comprehension levels, including customs Drupal sites.
We definitely want each Drupal site out there to join the party by simply install the appstore_client.module, subscribe to a good app store, or app stores, and start enjoying the benefits of apps. It should be noted that apps may be downloaded for free, or sold for dinero (see the discussion at g.d.o. )

What it actually means, is that we’re focusing on building the app store as generic as it can be, and with very basic assumptions. For instance, installing all of a module’s dependencies and their own dependencies, but without updating any already-installed module without an approval from the site owner.

On the other hand, asking for approval like “Installing this app requires an update to ‘Views’ module version from 3.3 to 3.4. Please approve.” is probably wrong and counters the whole idea of apps...
In many cases, site owners don't even know they have a “Views” module installed (wtf...??), and for sure they can not approve or reject this upgrade without fearing of utterly breaking their site.

Installing an app without updating all of the dependencies mentioned in the app’s manifest, may cause unknown behaviors. Yet, this is still the least worst behavior, comparing to breaking the website.

We encourage you to test our alpha package at http://drupal.org/project/appstore and give us feedback (or even better - jump in and join the ride!)

Nov 22 2011
Nov 22

The problem:
When clicking "add more values" to add another field to a cck multi-value field, and if you're using ckeditor, the existing multi-value fields will disappear.

So, if you have cck multi-field, and must use ckeditor, here are 3 useful things to do:

  1. Detach the ckeditor instances before attaching them again:
    http://drupal.org/node/712846

  2. Set rtl / ltr:
    http://drupal.org/files/issues/457620-ckeditor-direction.patch

  3. In the wysiwyg module's profiles, set the css to be used to "define css" - then it will load again after ajax is run.

Oct 16 2011
Oct 16

The National Roads Company (better known as the department of public works - Maatz) is one of the largest websites in the Israeli public service (as for now at least) and it's using Drupal. The website sets high standards with regards to the quality of public services (needless to say - only as far the website goes... we have nothing to do with the quality of the roads themselves ;) ).

Being a website of a large governmental authority, it literally paves the way for more public service agencies websites, which will use open technologies and high standards of availability, accessibility and last but not least - compatibility (as oppose to it's older version).

The website displays traffic reports and alerts, more or less in real time, with dynamic road numbers (see our blog post: How to add a magnifying glass overlay to a lightbox icon). Similarly displays reports on work sites. Furthermore the website provides information about projects in which the company is involved, and a directory of approved products for use by contractors in the roads domain.

The website has several interfaces with external systems such as SAP, traffic control systems, bids and tenders system, and eventually a live webcam of road sections and intersections.
More in the website - a notifications system which allows registered users to define exactly what interests them, and get updates for that specific subject. This sub-system is designed for contractors and other suppliers of the company, who wish to stay informed about new tenders and to respond in time.

The website will soon offer English and Arabic versions.

Oct 05 2011
Oct 05

Linnovate is a long time known member of the global Drupal community. As such, we always preach for positive activity in the community, participation in discussions and in improving the experience of Drupal users and developers all over.
While our members are not always present in the global forums (we're more active in our localized channels in Israel/Hebrew), we do try to give back by releasing our work as open source code.
More than in previous times, we have managed recently to release more modules, which were developed as part of our projects. This is, of course, aside to many improvements and fixes to existing projects.

Here are some of the modules we released lately, try them out!

Features Tools

Without any doubt, the Features module is one of the greatest contributions to Drupal since Views. It has changed the way we develop for Drupal drastically, and not only it has improved the deployment path, it is also the basis of apps in Drupal. YET, while it has many benefits, the Features module is also the source of many headaches when it comes to overrides and modifications by clients.
Features Tools contains two helper modules for developers:

  • Unlink Features: Upload the feature to a production server and detach some components from it, so the client can change it, without creating overrides and conflicts. This module allows you to safely maintain features on production servers.
  • Features direct save: This module adds a shortcut button for Recreate-Download-Untar-Reinstall a feature. Saves you a few precious minutes each day while developing with Features.

965

965 is the best of all worlds - Responsive layout, fixed and fluid grids (from 960gs & omega), HTML 5 templates (from Boron), CSS resets, media-queries and many more goodies thanks to html5boilerplate and modernizr. You'll love it!

Per Page Queue

Create Semi-automatique related content lists with this extension to the nodequeue module. Create nodequeus with path context and more. This is our third or fourth extension to nodequeue over the last two years.

Git tag

A life-saving tool which allows a developer to pull the latest changes to production or dev environment, without direct (ssh) access to the server itself. No more free and uncontrolled access to the server. A life saver I'm telling you! :)

Random IDs

If you just launched a website and you want people to think it's been up for years, or just hide the fact that you only have few dozens of nodes, and not dozens of thousands, this module obscures the real number of nodes in a website by randomizing their NIDs. User IDs randomizing to come. Contact me is you want to co-maintain this module.

Dartik

Dartik is the dark side of Bartik

We hope to come back soon with more contribs from Linnovate. Meanwhile, we continue with activities in other areas such as:

  • Groups.drupal.org
  • drupal.org.il
  • Druapl Training
  • Drupal advocacy in the public sector
  • Developing products over Drupal
  • #drupal and #druapl-*

See you around!

Sep 18 2011
Sep 18

After the great succes of Open ideaL, our Drupal based idea management platform, and as part of our global strategy, we are working on a Drupal app store that will serve Drupal apps to various platforms (including Open ideaL of course). The subject was partially covered in London.
Several platforms function today with app-like modules, and in order to increase interoperability between the platforms, a g.d.o. group was set up, where different providers try to reach an agreed format for apps.
Linnovate will use the standard in order to build a server-client model, where independent stores will be able to provide apps to Drupal websites and cloud based services. Having several Drupal app stores will create new business opportunities for independent developers and Drupal shops, and will ease the adoption of Drupal by those who are used to the apps model (notably in the mobile platforms). Installing a new functionality in Drupal should be as easy as installing an app on your mobile device.

Come join the discussion: http://groups.drupal.org/node/175329

Aug 23 2011
Aug 23

The past 3 weeks where insane.
Utterly insane.
If you haven't been following the news - one of Israel's biggest civil protests has been going on for more then a month.
I won't go in to the reasons and dramas behind the protest but like many protest in our region lately social-media, smartphone use and the internet are key enablers for the transparency and organization ability of the crowd.
This dynamic created one of the most interesting beta environments a product could launch with.
We donated an installation and modification of our Innovation management platform - IdeaL which let's the people voice their opinion and enables the protest leaders to understand the controversies and consensus of the crowd and focuses them while dealing with the govermental comitees.
Ideal was implemented initially in the ohel.org.il - the official brainstorming and policy forging site.
The Israel government spotted the advances in the platform since it's first incarnation in shituf.gov.il and ordered another installment in http://hidavrut.gov.il/.
The irony is that hidavrut is the platform for the committee which is supposed to discuss with the protesters (which are powered by Ohel).
So... Ideal is experiencing one of the most intensive betas of direct democracy in the past two weeks and we're constantly challenged by what the different sides require.
While ideaL still gets some polishing, if you want to help out or give ideaL a spin you can clone it's implementation at https://github.com/linnovate/IdeaL--ohel.org.il-

Apr 25 2011
Apr 25
We have been hacking with android and drupal for quite a while but we finally got a chance to give "DrupalNews" some love. Our inspiration for updating the app was based on Johan Falk from nodeone, who built a bunch of RSS feeds which are more fitting to the new github/sandboxed era on drupal.org. This got us back on track integrating the new feeds and rethinking the app. As we played with the app (and reflecting on node one's kitten killers meme) we understood that we need another feed - The culture feed. This feed is the collection of all of those cool moments which consist of Drupal s culture. We started hosting that feed but when I told Johan about it and he bombarded me with a bunch of new drupal moments, I understood that this should be released - https://drupal.org/sandbox/liorkesos/1126176 Currently I, Johan and Dries have commit rights but we're accepting cultural patches :)
Mar 23 2011
Mar 23

We recently had a client request to search inside user's uploaded Documents for some online tenders.
Dupal's apachesolr and apachesolr_attachments modules with Apache's solr do the work but we have an exotic language and.. exotic challenges...
When extracting text from the uploaded PDFs - the uploaded Hebrew PDF indexes the words backwards (not being aware to Right To Left text)...

The default behavior of apachesolr_attachments is to use Tika (through solr or application) to extract text from uploaded documents.
the text extraction was correct for Hebrew .doc and .docx files but not for PDFs.

a quick fix for that was to use PDFBox application CLI to exctract text from uploaded PDFs.
this corrected the Right to left awareness issue.

apachesolr_attachments module - http://drupal.org/node/840056
patch to use pdfbox cli: apachesolr_attachments_pdfbox.patch

Mar 07 2011
Mar 07

Come meet us at booth #73!

Linnovate, with our current brewing partner Kaltura, is handing out a bunch of Drupalager T-shirts at Drupalcon Chicago!

To get a chance to win a T-shirt, you need to do two very simple tasks:

  1. Follow us on twitter (@linnovate)
  2. Tweet: "I want to get a #Drupalager T-shirt at #drupalcon by @linnovate http://is.gd/drupalager" (or use the QR code on that page to grab the text)
Mar 01 2011
Mar 01

We've been working lately helping kaltura port their module to drupal 7.
The cool insight I found is that once we where able to migrate the kaltura node to a fieldable entitiy, their is tons of stuff we can now do with video fields associated to various elements.
Just though of sharing some of the usecases I toyed with.

Video on Comments
Let's say you want to communicate soley using video.
You post a video in a node and the commenters answer inside the comments by recording a video of their selfs from the kaltura field in the comments

Video powered bio for Users:
Imagine a linkedin clone or a dating site with an intro video per user.
By associating the kaltura video field to the user we can have his bio as a recorded video - instead of the classic bio text.

Category video
Imagine taxonomy image on steroids! , The Kaltura field can be any type of media (picture, audio, video).
Now think about a site that has a category for elephants - you could post the taxonomy video in the head of the taxonomy page, showing a video about elephants alongside the tagged nodes.

If you're going to DrupalCon Chicago we'd love to show you some d7 kaltura coolness in our booth (#73) Stop by and grab a (drupal)lager as well.

Dec 28 2010
Dec 28

We started using GIT SCM for all the new development projects.
GIT's advantages are widely discussed elsewhere- it is fast, efficient, and is a DVCS.
The reason that is important is that it's much faster than SVN and the branching is so easy you don't think about it much as you develop (much less SVN merge drama :) )
One of my motivations (as the CPO in Linnovate - Chief Paranoid Officer) is not to open ssh for too much people in my production servers (not even to our developers!).
That was the motivation behind git-pull it provides a useful mechanism which lets developers easily update the code of a development site.
(right now this module can actually be used for both SVN and GIT code updates)

Setting up this module requires some Operating System configurations, the reason is file system permissions guidelines of a Drupal site (the user which runs the web server should not have access to change or create any PHP files).

This setup is based on Linux..


  • Protecting .git folder from 'prying eyes':
    The default .htaccess file of Drupal 6 doesn't include a protection for the .git folder.
    to protect it - simply add a rewrite rule after the RewriteEngine directive:

    RewriteEngine on
    RewriteRule "(^|/)." - [F]

    the above directives will protect every name with "." in the beginning.
    Drupal 7 already includes this protection.
  • configuring /etc/sudoers:
    allow the web server's user to run git pull command - (usually apache or www-data on Linux):

    www-data ALL=NOPASSWD: /usr/bin/git pull

  • edit git_pull.module file (TODO - move it to settings.php).
    change in lines 'aegir' to the user which have write access to the PHP code files and document root.
    line:
    <?php
    ...
    $command = 'cd '. $root .'; sudo -H -u aegir git pull 2>&1';
    ...
    ?>
  • enable module - and You will have new button in Drupal admin's menu - 'GIT PULL'.

Another module for managing a Drupal development site using GIT is gittyup.

Dec 20 2010
Dec 20
One of our favorite client that we are very proud of, and we accompanied from our early days, is www.MachsomWatch.org. Lately we upgraded it from drupal 5.x to drupal 6.x and dressed it with a new beautiful design by Inbal Mizrach. As long with the design, an extreme UI process was made, what made us actually build, almost the entire site from scratch, over the existing content. One of the interesting challenge was to combine the checkpoints content with the daily reports from checkpoints. *A checkpoint* - is a description of the checkpoint with map, flickr images and videos from the checkpoint. *A daily report from the checkpoints* - is a daily report from one, two, three or more checkpoints, which tagged with those checkpoints tag. The goal was to eliminate the checkpoint page, and under it to display the latest report from that checkpoint, and to make the checkpoint as a context for paging through daily reports from that checkpoint. One more thing is to display the description, map, flickr images and embed video from the checkpoint context. Keeping the original paths of the daily reports was a must, according to the amount and their google rank. We created the check points navigation by going over the checkpoint terms and links them to the latest report from that checkpoint, while adding the tid (checkpoint) as a query to the path. Well, it looks something like that: created; $node_type = $node->type; //Get the checkpoint tid from the url query. $current_tid = $_GET['checkpoint']; //Return the prev result for the same checkpoint. $prev_res = db_result(db_query('SELECT n.nid, n.title FROM {node} n INNER JOIN {term_node} t ON n.vid = t.vid WHERE n.type = “%s” AND t.tid = “%s” AND n.status 0 AND n.created 0 AND n.created > %d ORDER BY n.created ASC LIMIT 1 ', $node_type, $current_tid, $node_created)); $urlquery = $node_type == 'content_daily_report' ? 'checkpoint=' . $_GET['checkpoint'] : NULL; if ($nid = $prev_res) { //Build the links with the name of the link, href from the prev report that we found //and passing the link checkpoint as url query. $items[] = l(t('prev'), "node/" . $nid, array('query' => $urlquery)); } else { $items[] = t('prev'); } if ($nid =$next_res) { //Build the links with the name of the link, href from the next report that we found //and passing the link checkpoint as url query. $items[] = l(t('next'), "node/" . $nid, array('query' => $urlquery)); } else { $items[] = t('next'); } return theme(checkpoint_daily_report_pager', $items); ... ?> As long as we keep getting the checkpoint query from the URL, and passing it to the next one, we are keeping the context alive.
Nov 16 2010
Nov 16
Good content brings good comments with it, and good comments improve the post they are related to, so in a site where users are rewarded for their ideas and contribution, it is just a matter of fairness to let the commenters of a good post to be rewarded as well. In our ideas management system, we want to grant points to each comment author when the post is tagged with a specific term. So far this is impossible with rules.module . In our example, we'll try to grant 1 point when the post is tagged as “Under review”, and 2 points when the post is tagged as “Launched”. One more requirement is to keep it exposed to the administrator through the rules UI, so she will be able to grant more or less points, add or change tags or even switch to flags instead of terms (or any other condition or action). **Few words on rules sets:** A "rules set" is a group of rules with no trigger (event). When creating a rules set you can select the arguments which will be passed to the set once it is invoked. In our case we will need to identify the user to grant points to, and the content (node) to check for the specific term. To fire a rules set we can invoke it through code like in our case or from a triggered rule. First we’ll create a rules set and name it “points to comments authors”. Now lets add two arguments: 1. User 2. Content *Figure 1 - Rules set arguments settings (Don’t forget to tag your rule sets and your rules to make them available for exporting with features).* Then we’ll add two rules under it named as: - Under review comment author points - Launched comment author points Now lets set the first rule. As a condition we’ll select “content has term” which is a custom rule condition that we added. Create a file in your module folder named MODULENAME.rules.inc and add those lines:
Jul 29 2010
Jul 29

We're very proud to see the first fruit of several months of work and several year of building the Drupal enterprise eco-system in Israel.
The first site shipped, http://shituf.gov.il is a site which exposes the latest rules and discussions from the government to the public.
That way legislators get a very short feedback loop on the current activity and the public gets to state it's opinion and vote up or down on the stream of new rules and political activity.
This "political digg" is the first time in Israel where official governmental activity is letting the public create content in the website and the first time Drupal and it's underlaying open stack is used in official governmental hosting.
The site is seeing great engagement (for instance a rule about monitoring the state of israeli education had 544 votes, divided almost equally and hundreds of comments.
Shlomi Tsadok, Our reprasentitve in the government has led this project and we are showing day after day the flexability, ROI, lower TCO and general awesomeness which is Drupal.
YADGSCTL - Yet Another Drupal Govermental Site Comes To Life (I'm not sure about the popularity of the acronym, but Drupal is gaining popularity in Enterprise Israel and that what counts :) ).
World Domination is now.

Jul 16 2010
Jul 16
In this post I would like to show a way to combine Drupal OSM (open street maps) interface with websockets push technology, in order to allow drupal based sites to work as a real-time online monitor, for real world physical actions. Unless you are already familiar with the terms that I have mentioned so far, you probably don't really understand what I am talking about, so as a prologue I'll elaborate on a few key terms: 1. Websocket is (simply put): a port which is assigned to "listen" to changes in the remote client's data and notify your client without polling or busy-waiting-type techniques and thus saves a lot of time,web traffic and battery time (important when using a mobile device). 2. Push technology: as it is called is a technology used to push information into a designated listener websocket. 3. OSM: an open-source project which is essentially a copy of the Google maps project but with more customization and localization. OK, so after you understand the basics of what we're dealing with here let's put it all together: 1. Install the Geo and OpenLayers modules for Drupal and create a view with an "OpenLayers data" display to create the map. (for more information go to http://openlayers.org/). 2. Create a customized js script inside the theme folder of the site which incorporates websockets in order to create the listener. (for a great and easy way to start try: http://pusherapp.com/ ). 3. Now, use the same technology to implement a trigger application to your Android or Iphone mobile device, since both of them have methods which are triggered only when you move there's no polling here either so it's not that heavy on your battery or your 3G account. And there you have it: a Drupal site with a map that shows your device's location on a real-time online map.... think of it as Stalker2.0 :^) For a taste of what i talked about in this post, take a look at the video- it's in Hebrew but I added some annotations so you can figure out what's going on have fun.
Jul 15 2010
Jul 15
I'm attending Startup Weekend in TLV which is turning out to be a really great and colorful event. One of the coolest things is that I finally got to meet Tim Cullen which is leading the development of a local Drupal community in Ramalah. I'm a big believer in the epic power of open-source to enable communication where none exists or where barriers (technological or political) might limit communication and innovation. I took ( a low quality and shaky ) video of Tim's presentation. This brings me to make the safe assumption that a local peace initiative can really help Drupal 8 adoption ;)
Jul 10 2010
Jul 10

Drupal 7 is going to introduce a lot of improvements, many of them regarding the user experience and user interface. in the past few days one of the greatest (and maybe the last) of these changes was committed - a new core theme, and not just a core theme but a new default theme for Drupal - that means that the mythological Garland, after almost four years, gives way to a new, fresh face for the next Drupal release.
bartik.theme, the successor, is named after Jean Bartik, one of the first computer programmers, and a woman. She worked on the ENIAC (with an all women programmers team) and the UNIVAC. and they have invented a lot of what we take for granted in the today world of computing.

While previous core themes were created by a restricted (2-3) group of developers, Bartik was created in a never-seen-before-for-a-core-theme group effort, a lot of amazing people contributed their time writing code, testing and reviewing, knowing that there is always a chance this theme will never get into core, not to mention become the default Drupal theme. I too had the honor of doing my share for Bartik - apart of helping with a few minor issues I have helped with the RTL styles of Bartik and with its unique comment form.

Bartik is not just a new default design for Drupal, this is a theme built from bottom-up to be a 2010, modern, flexible, stylish an still elegant and clean theme to go along with the awesome Seven as an admin theme and IMO even with the drupal.org redesign that flows very well with Bartik's blue-lagoon default color scheme. The concept was to create a good looking, multi-purpose theme that will keep the focus on the content, rather than on the theme itself.

Bartik brings with it a lot of improvements including the flexibility, unlike Garland, to become much more than the out-of-the-box Bartik.
Furthermore, Bartik brings the message of Drupal regions into core - that means that a lot more than just header, two sidebars and a footer are now available for you to really experience with Drupal core block module even without the use of contributed modules/themes/theming via code. another important improvement that Bartik introduces into core that for me as a hebrew speaker and for the whole drupal.org.il community is a real, a-la-tendu.theme RTL support never seen before in drupal core - that means, for example, that sidebars are flipped when you go from LTR to RTL so that the main sidebar is always situated before the content and the secondary one after, which brings us to quit the use of right and left in sidebars nomenclature, both of which might seem minor issues to an LTR person but are crucial for us RTL and Bi-directional developers. tendu.theme has, since Drupal 5, set an example for a well written Bi-directional theme and these ideas and thinking mode were slowly infiltrating core until (and we are very proud of that) Drupal 7 core itself will be the one to set the example for RTL support.

For the sake of fairness I must say that Bartik was not the only candidate for core, corolla.theme and busy.theme - both very beautiful themes were close but just not ready enough for core on the, already late, final moment. Even Bartik itself is not perfect just yet, the logic behind putting it as default now, is that this way it will get the maximum number of testing eyes so it will be as close as possible to perfect on the day Drupal 7 is released.

So congratulations to Jen, to the Bartik team and to the whole Drupal community for this achievement.
we have manage, once again, to make Drupal a little better.

Jul 08 2010
Jul 08
One of the classical challenges when working with maps is - How to set a map with two content layers, each with it's own markers color ( with no code involved ). We'll use the OpenLayers module that bringing the OpenLayers JavaScript library into Drupal. Although it's most convenient to work with, settings are not always trivial and can be a bit confusing at the beginning. We'll try to go over the settings process and pass through all obstacles. Drupal core - Drupal 6.x Modules – cck.module, views.module, openlayers.module ###CCK settings Each content that needs to be shown on a map, should contain the relevant geographic data, so first we need to add the Latitude/Longitude field for each content type which is to be displayed on our map. We are using the **Openlayers WKT (Well Known Text)** field which comes with the Openlayers CCK module. Other geo-data input formats, like the new geo.module module can be used as well). In the settings page select the "Input Map Preset" (see how to create and set preset in the Openlayers settings section below). The map preset will be displayed in the node edit form, to help us assign our points, lines and polygons visually. *Figure 1 - Node edit form - mark your feature straight on the map or by input WKT markup* ###Views settings Our map is built out of (at least) two displays of views. The first one is the data display named "*OpenLayers Data*". Each OpenLayers Data display will create a layer for our map. We can add as many layers as we need. Under the *style settings*, select the "*OpenLayers Data*" style (it's the only one there). In the settings under the *Map Data Sources* select *Openlayers WKT* (this is the data type we use). Select the WKT field we added in the CCK settings section (remember to add it first in the Fields box. The WKT field is the only required filed, although we probably want to add a title and a description as well). Any additional fields added under the Fields box, will be able to be selected under the other drop downs. If we select them, the will show on the popup/tooltip on the map. Remember to add filters as needed. *Figure 2 - The view form - OpenLayers Data display with OpenLayers Data style* The second type of display is the map display. We'll add a new page display and select the "*OpenLayers Map*" style under the style settings box. Select the map preset under *Style Settings* (we'll see how to set it up in the Openlayers settings section). Next, we need to set the page URL and menu item. ###Openlayers Settings **Layers** - In this page, in addition to the external layers that are included in the module, we can now see the layers we defined as a data display in our view. **Styles** – are referring to features (points/lines/polygons) on the map. Under *Edit* we can select color, shape, radius, image (optional), etc. Note that a style can be assigned for the features (again - points/lines/polygons) of each layer. **Presets** – Preset is define for each map-display, and include all the settings for the map. We now have at least two maps. The first one we defined as CCK field to assign features on the map, which will appear in the edit form (to assign the preset to the field use the field's setting page). The second one is the main map that we defined in the views map-page display. We have assigned that preset in the views map-page display in the style settings box. This means that we need at least two presets, one for each map. First, we'll set the general information for the name, title description, and dimensions. Then, under the Center & Bounds, we'll figure the initial focus and zoom for the map by simply setting it visually. Under Behaviors, we'll select the ones we would like to add to our map. Zoom bar, layer switcher, popup, fullscreen button, permalink, etc. Finally, under *Layers & Styles settings*, leave the default settings – 900913 for map projection and 4326 for display projection. This should be fine for most cases. Under Base Layers, select the background maps images that serve you the best. Under the Overlay Layers we'll see the data layers that we created in our view. Here you can enable, activate and assign the styles to the features of the layer. *Figure 3 - The preset form - Select the map and and the layers will be available for display.* That's it, here is our map with two content layers, each with different markers color. *Figure 4 - The map.*
May 24 2010
May 24

About a week ago we launched the Drupal News application for Android. We only worked few days on it, and it's still not perfect, but it does give a wonderful service to Drupal users.

For the proof of concept, we used Drupal.org's feeds:

We also pool #drupal from twitter, and present it as an independent tab.

All this are now available inside an Android app, and can be carried along as you go :-)
While the app can still be improved, it is an immediate solution for every Drupal site out there, who wishes to publish it's news as a stand alone app on an Android device.
We still haven't published the code, but it will be published, and open sourced. Once you have it, you can customise the feeds and twitter feed to follow, so you can present your users your news and have an instant android app for your Drupal website!

How to get it?

Scan the QR code right above here, or search for drupalnews on the market - it's there!

Drupal News Android Application QR code
May 10 2010
May 10

In the last couple of years we used to integrate a lot of interactive flash content on our sites.
Flash gives to the end user a lot of interactive web richness that is nearly impossible to reproduce on other current tools we have today.
The emerge of html5 is very exciting and we can't wait for this protocol to gain more power - but with all that said in the current state it is still hard to give cool solutions to our clients that require a lot of logic or UI that is beyond the current capabilities of Jquery UI.

To integrate flash/flex content we use the highly recommended swftools module. It gives us the ability to add flash content using the "Drupal way" - simply by calling the swf() function.

With our goal to extend our capabilities to the mobile industry, we wanted to make sure we can offer a nice user experience for devices that don't support flash. This is easily achievable using a built-in feature in swftools, that allows to replace the flash content with supported html markup (like image or html5 canvas).

here is how we do that:

<?php
$flash_replacement
= '<img src="http://www.linnovate.net/blog/swftools-replacement/image-replacement"/>'; //here you insert the replacement markup
$file = 'http://...'; // insert here the path of the swf
$args = array(
             
'params' => array('width' => '100%', 'height' => '100%'),
             
'othervars' => array(
               
'html_alt' => $flash_replacement,
              ),
            );
print
swf($file, $args);
?>

As you can see this is pretty straight forward - you just need to add a value to the 'html_alt' key inside the 'othervars' array and that's about it.
You can insert any markup you like (even a theme function).

Check out our home page flash banner as an example.

May 02 2010
May 02

In this screen-cast I plan to show you a new module we are creating called - http://drupal.org/project/form_extended This screen-cast is brought to you by using the Sparkeo video platform - we helped to build

The Drupal form API comes with default generic properties.
The form extended module, lets other modules extend the form API and add their own custom properties.
To create a new form property a module needs to define a plug-able handler. Then each module can use those new properties in it's forms or manipulate other forms using hook_form_alter and Rules form support, on the same way you can manipulate a native property.

This module is still in development and i'll be happy to hear from the community any thoughts and comments they have on the idea itself and its implementation.

Apr 19 2010
Apr 19

In the following week we've developed an android application to manage drupalcon oriented information.
Currently we only have the sessions info in place but our vision to the next drupalcons is to add twitter based activity streams, relevant map info and to become a one stop shop for your mobile experience using android.

To find the app search for drupalcon in the android market.

There is a very comprehensive mobile version of the drupalcon site which has more features built in - it's optimized for webkit and iphones yet it works well with android as well.

We're very excited about providing android native applications to our customers and we'd be if you (or your customers) need native android app support tailored to work with Drupal - try to find us in Drupalcon.

Apr 19 2010
Apr 19
Drupalcohol by Ben-Hana winery and Linnovate

After Drupalager and Drupalager 2009 we decided to explore new directions for this meta category we've created - Drupalcohol.

Shlomi Tsadok, one of our newest recruits, who is leading the team integrating Drupal in the Israeli government, is a big wine fan - so big that he quit the computing business to open his own winery in 2003.
He exports 4000 liters of Wine a year (mainly reds) and is our latest "brewing partner" (after yhager and hinbit in the previous batches).

We are proud to be part of this community and to try to find fun ways of promoting Drupal!

Mar 31 2010
Mar 31

In one of the most epic chapters of Sienfeld - George and Jerry are confronted with the Dillema "Tuck or No Tuck"?
A brave group has decided that this Dillema must be resolved and that blankets (like people, data and source) should be free!

They started the liberation front and have founded - "Free The Blankets!" a site with one clear agenda and goal - Untucked blankets by 2020.
Aren't you sick and tired of entering your hotel room and fighting with the tightly tucked blankets messing up everything in the process?!

Like George, We are free spirits, and can't be confined to the atrocities of maids stretching blankets to confining walls.
Now note it is not the maids fault - IT IS POLICY! and because of this it will be resolved by the policy creators - the managers and boards of Hotels and Hostels.
Joining this effort they will create a social movement that will free the blankets and will let us wake up at a fine morning in 2020 (or sooner!) stretch are legs and sigh...

Pages

About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web