Case Studies
Type in the API key
We will get the API key for you
"oAuth Pure"
ExpenseBooks - oAuth
Mobomo webinars-now on demand! | learn more.
Case Studies
Type in the API key
We will get the API key for you
"oAuth Pure"
ExpenseBooks - oAuth
With so many devices and screen sizes, it can be difficult balancing act to make your site look great and perform well. Displaying low res images on a high res display can make a site look terrible. On the other hand, serving high res images to a low res device can needlessly create a sluggish experience. Responsive images can help.
NOTE: Responsive image techniques are best used for CONTENT images (<img src=””>). For background images, you can and should use CSS media queries to control how the image is displayed across various devices.
The goal of responsive images is to provide multiple image sources and any other details the browser may need when deciding on an image.
WARNING: Parts of the syntax are very weird and the results may seem weird due to the long list of factors at play. These factors include, but are not limited to:
Viewport size
Image size
Image display size
Screen Pixel Density
Cache
Browser
*Bandwidth
*Browser settings (User preferences)
*Not currently implemented
Introducing the source set attribute:
Srcset allows us to provide multiple image sources as well as the size of each image. It may seem odd to inform the browser of our image sizes, especially since the browser can easily determine this on its own. However, the reasoning behind this is to give the browser a leg up on the selection process; allowing the browser to intelligently decide, prior to downloading, which image to request.
Taking it one step further with the sizes attribute:
The sizes attribute allows us to inform the browser of the image size being displayed on a page. It includes syntax similar to CSS media queries for responsive layouts where the image display size is determined by the layout.
Again, it may seem odd to inform the browser of something it can easily calculate on its own or it may seem odd to include redundant code from CSS, but providing this info before the browser even has the CSS files will improve performance.
A bit more control with the picture element:
Lastly, the picture element provides more control, using media queries, to explicitly narrow down the browser’s selection of image choices. This is useful for implementing art direction or when image sizes change so dramatically they must be uniquely cropped for every layout.
Responsive images can be complex. However, when done properly, they can provide the very best experience for any situation.
For more details check out our codepen:
[codepen_embed height=300 theme_id=1 slug_hash='qdMQdb' user='Mobomo LLC' default_tab='result' animations='run']

For the last eight years, I’ve been doing the design thang, working with companies ranging from a two person team to a large open floor creative group. Adjusting to these various structures was second nature, and not something I ever gave much thought to until now.
With the recent merger of our two design teams - Intridea and Mobomo - a unique opportunity to assist in the restructure and building of our teams was brought to the table. I know this isn’t an isolated situation and the process is in no way easy!
Thus, for the greater of mankind, I will chronicle our journey; the highs, the lows, and everything in between! I’m shooting for a four part series, breaking each post into specific topics: structure, process, tools, and culture.
I went bananas scouring articles on best practices, must haves, and shit you never do! Everyone has their own “right way” to structure a team - some work, most don’t. And while the ways to structure a team are extensive, the golden ticket wasn’t really structure but specific traits that differentiated a successful from a “meh” team.
Now, like anything, if you don’t establish a solid platform - that jenga tower is gonna fall! So let’s ask a few questions:
As mentioned above, I’ve worked in an array of team structures, but what’s been most effective, not only in my career, but in my research, was that of a “traditional” formation. One involving directors at the top, followed by senior leaders who then oversee the junior level folks. Why does this approach work? There’s a funnel, a singular route of communication, and a cascading approach to mentorship.
Directors drive their team to ask the tough questions; pushing them to think in a different direction, from a different angle. You know never know if the problem you’re solving is the right one, until you ask “why”.
Senior designers are your battle hardened troops, the ones who can articulate and defend their position on a specific choice with facts and rationale. They’ll choose right, over right now, and will fight for what’s correct. They’ll also help mentor and develop junior designers, guiding them to make smart choices and back up their own decisions.
Junior designers will eventually take over the reigns for their senior counterparts, so it’s vital that they learn and develop the key attributes that will make them good mentors one day. Find people with the qualities your company values: hire slowly - fire quickly.

Now that we’ve figured out who to hire, we need to establish what kind of team we want. Should our team of designers also know code? Eat and breath exceptional design, and only design? Or should we focus on a strictly UI design team?
What I’ve seen, and what I’ve read, all seem to point to the same thing, diversity! Find folks who bring different strengths to the table and push one another to do amazing things. Though, I should say, there are some must have skills each designer needs:
Most of the other attributes can be taught or learned as they progress.
Finally, what’s the goal of your team? What are you trying to achieve? For fear of sounding like a cop out, I’d like to revisit this question in the next post. This is a new venture for all of us, and seeing as we don’t really have a team yet, I can’t say what our goal is. I do know that it will involve creating amazing work, with amazing people, but as for concrete and tangible goals: TBD.
Got any insight on team restructures? Let us know!
It's here! Inc. 5000 released their list of the fastest growing, privately-owned companies for 2015. With a focus on job development, revenue and year-over-year growth, Inc. Magazine ranks the best of the best in the entrepreneurial world.
Coming back for another year, Mobomo has made the Inc. 5000 list once again! With a revenue of $5.6 million, 50 additional members to the team, and a three year growth of 194%, Mobomo is full-steam for 2015. Woo hoo!
Want to learn more? Chat with some Mobomo folks? Or heck, just say hi? Tweet, FB, or contact us! We'd love to hear from you.

I’ve previously written about the power of the Ionic CLI, which offers some great tools to developers building mobile apps using web technologies. While Ionic offers a CLI and mobile-optimized UI components, it doesn’t handle native level integration, for example accessing a user’s camera, or contacts. Since Ionic is built on top of AngularJS, we can use Angular to access native plugins, and this is where ngCordova comes in.
ngCordova is a framework that makes the native Cordova API available as AngularJS services. In this post, I’ll walk through setting up ngCordova, and accessing the contacts on a user’s device. First, a few prerequisites. You must have the following installed on your machine:
I’ve created a Git repository that you can checkout and follow along with, or you can create a new repo and progress through the steps on your own.
First, you’ll want to create a new Ionic app by running this command in Terminal:
ionic start ionic-ngcordova
This starts a new Ionic project, in a folder titled “ionic-ngcordova”. That last bit is arbitrary; you can name it whatever you’d like. Also, this will by default use Ionic’s “tabs” app template (there are others, like “blank”, or “sidemenu” available).
Next, a few housecleaning items I tackle with any new Ionic project. In Terminal, change directories (cd ionic-ngcordova) so you’re in the folder Ionic just created, and enable Sass:
ionic setup sass
Next we’re going to add a few directories to the Git ignore list that shouldn’t be included in our repo. To do this, open the project directory in your favorite text editor. For me, that’s Sublime, so I can open the current directory, with the folder structure visible using:
subl ./
With the project open in your text editor, locate the .gitignore file in the root directory. We’re going to add the following lines to the bottom of this file:
hooks/ www/css/ www/lib/
The hooks directory includes native Cordova JS that’s managed by Ionic, the www/css directory contains your compiled CSS (generated by Sass), and the www/lib directory is where Bower places all its assets (check out the .bowerrc file in the root directory for more info here).
With these steps complete, we have a nice clean repo, and you can run the app in a browser or the iOS Simulator via the command line to make sure everything is working:
// Browser ionic serve // OS Simulator ionic emulate ios
Now for the fun stuff. Back in Terminal, in the project root, let’s install ngCordova:
bower install ngCordova --save-dev
This installs the ngCordova package (specifically, in www/lib/ngCordova), and saves it as a dependency in the bower.json file in the app root (The --save-dev flag, a good habit to get into).
Back in your text editor, open up the index.html file, located at www/index.html. This is the root HTML file that your app runs on. Now that Bower has placed the ngCordova library in www/lib/ngCordova, we need to reference ngCordova’s JavaScript file in our app’s index.html file. Include this line after the line that includes the bundled Ionic/AngularJS file:
<script src="lib/ngCordova/dist/ng-cordova.js"></script>
Next, we need to inject ngCordova as a dependency into our AngularJS app. This is done in the app’s primary JS file, located at www/js/app.js. Following the other default controllers and services injected by Ionic, add ‘ngCordova’:
angular.module('starter', ['ionic', 'starter.controllers', 'starter.services', 'ngCordova'])
ngCordova is now available to our app, and we can install and start using any of the native Cordova plugins listed in the ngCordova docs. Let’s see how we’d access the user’s contacts using the $cordovaContacts plugin.
First, we need to install the plugin using Ionic:
ionic plugin add cordova-plugin-contacts
This installs the Cordova Contacts plugin in the plugins directory in the app root. The ‘ionic plugin add’ command is essentially the same as Cordova’s ‘cordova plugin add’. Check out the Cordova docs for more info here.
Now that we have our native plugin installed, let’s emulate using the iOS Simulator, also using the livereload feature of Ionic’s CLI:
ionic emulate ios -l
This will launch the app in the iOS Simulator, and reload in real time as you make code changes in your text editor.
With the app running in the iOS Simulator, we’re only a few steps away from accessing the user’s contacts. First, we need to inject the $cordovaContacts service into the controller where we want to access the contacts from. I think a user would probably access contacts from their Account tab, so let’s open up www/js/controllers.js, and inject $cordovaContacts into the Account controller:
.controller('AccountCtrl', function($scope, $cordovaContacts) {
With the service available to our controller, we’ll add two buttons that will allow the user to select a single contact, or multiple contacts, respectively. Open up www/templates/tab-account.html, and add this markup following the closing tag. This will use the standard Ionic button markup:
<button class="button button-positive button-block"> Get Contact </button> <button class="button button-positive button-block"> Get Contacts </button>
Now for the magic. Our last step is setting up a function to be called when the user touches a button, and calling the $cordovaContacts appropriately based on which button they’ve touched.
First, let’s add the click handlers using Angular’s ng-click directive:
<button class="button button-positive button-block" ng-click="getContact()"> Get Contact </button> <button class="button button-positive button-block" ng-click="getContacts()"> Get Contacts </button>
At this point, your app should look like this:

Lastly, let’s create the functions in www/js/controllers.js. In the AccountCtrl controller, add the following lines after the $scope.settings object:
$scope.getContact = function() { $cordovaContacts.pickContact().then(function(result) { console.log(result); }); } $scope.getContacts = function() { $cordovaContacts.find({multiple: true}).then(function(result) { console.log(result); }); }
If you hit ‘c’ in Terminal, this will enable Ionic’s console logs feature, and you’ll see the contact objects being logged as you touch the buttons. Alternatively, you can launch Safari, then go to Develop > iOS Simulator and visit the full Safari console there.
You’ll notice that touching the “Get Contact” button launches the native iOS contact picker component:

The “Get Contacts” button simply grabs all the contacts on the device and dumps them to the console, in all their gory detail. Creepy:

While ngCordova is the bridge that allows easy access to Cordova plugins via AngularJS, all the Cordova plugins available have more documentation than is found on the ngCordova site. You’ll notice an “Official Docs” link on each ngCordova docs detail page, which points to the original Apache/Cordova documentation, for example the official Cordova Contacts documentation.
Hopefully you can see how in just a few steps, we’re able to setup a new mobile app using Cordova, leverage Ionic’s tools and UI components, and further layer in ngCordova to access Cordova plugins via AngularJS.
Any questions, thoughts, ideas? Let us know!
Want to learn more? Check out Intridea's posts on Ionic CLI and Ionic Experiments
True to our commitment of knowledge sharing, Mobomo’s CEO, Brian Lacey and Project Manager, Malena Lopez visited Martha’s Table last week to speak with smartART interns on mobile app development.
smartART (Awareness Relationships Technology) is a program challenging teens to delve into issues impacting their lives, bring awareness to their community and be the change. The program helps foster critical thinking, collaboration, creativity and communication skills via art projects, oral presentations and technology.
This summer, the Summer Youth Employment Program (SYEP) students were Content Developer Interns. Tasked with app development, these students designed applications addressing the issues of literacy education, health and nutrition and making good decisions.
During Mobomo’s visit, the interns had the chance to peek into life as an app developer and ask any and all questions! So what exactly did the interns learn?
Best of all, the interns learned the importance of creativity in the dev world.
Interested in learning more about our mobile strategies? Send us a tweet!

There’s been a lot of buzz around Google’s Material Design recently, from Material Design Lite (Google’s non-JS implementation of Material Design), to Angular Material (Google’s Angular port of the Material Design library), to Ionic Material (a non-Google project that builds on top of Ionic’s UI), and even Google’s Material Design implementation with Polymer’s Paper Elements.
Envisioning a scenario where a client has heard of Google’s Material Design, and requests it as the UI basis for a mobile project, I set out to see what would happen when we start to implement some of these new front-end options in an Ionic/Cordova app.
Angular Material is an implementation of Material Design in AngularJS, that’s supported internally by Google. It provides UI components from the Material Design library as easy-to-implement AngularJS directives, and has a strong focus on accessibility, which is a big concern with AngularJS apps.
The demos for Angular Material are very well fleshed out, and it looks promising. I was able to integrate into Ionic easily, as both run on AngularJS. I spent almost zero time on CSS, but I was able to achieve comparable results.
Here’s what the Angular Material md-card directive looks like (Ionic on the left, Angular Material on the right):

Here’s what it looks like when you swap out the Ionic list directive with the Angular Material list directive:

I’ve created a demo repo if you’d like to see the changes I made, and download, run and play with the implementation yourself.
Ionic Material is not maintained by Google, but has some pretty slick demos. It’s designed to be layered on top of Ionic, and enhance the existing directives, meaning it’s even less of a switch than implementing Angular Material.
Upon setting it up in the app, I didn’t really have to change much other than adding Ionic Material to the project, and already the “material” design impact is felt:

I’ve also created a repo showing the implementation of Ionic Material in an Ionic app.
Is implementing Polymer in an Ionic app a good idea? Who knows. Probably not. I wanted to see how far I would get before running into issues.
Implementing Polymer in Ionic was fun, and the bonus here is that you’re using web components which are on track to be standardized in browsers, so you have to love the compatibility forecast. I was able to replace Ionic’s header with Polymer’s paper toolbar, I added Polymer’s iron-pages and paper-tabs in place of Ionic’s tabs, and converted the layout to use the paper-scroll-header-panel web component.
This screenshot is taken as the touch animation is firing on one of the tabs:

I’ve created a repo for the Ionic Polymer experiment, so you can check out how that looks locally.
Angular Material is currently at 0.10.0, so I ran into components that didn’t work pretty quickly. That FAB Speed Dial component sure does look snazzy, though. It’s an internal Google project, so I expect we’ll see a lot coming soon. Since it’s so early in the development, I’m going to put this one on my watch list and kick the tires again once a bit of time has passed.
Ionic Material is even earlier in its development, currently at a 0.0.1 release. It will probably be the easiest to implement, once its ready. While not an official Google project, this is also one to put on your watch list.
Polymer starts to clash with AngularJS pretty quickly. For example, I ran into issues with data binding, and I really was just scratching the surface. It’s probably best to implement Polymer as a Cordova app, without Ionic, so you avoid these conflicts. Of course, you also lose a lot of value if you remove Ionic from the equation, so there’s room for discussion, depending on the project.
Hopefully this has given you some insight into the recent developments surrounding Google’s Material Design library, and how they might fit into your Ionic mobile app development cycles.
Any questions, thoughts, ideas? Let us know!
Want to learn more? Check out Intridea's post on Ionic CLI.

There's been a tremendous push in recent months to move all of the components used for building anything for the web in to JavaScript, and only JavaScript (abandoning the use of HTML for templates and CSS for styling). While I can understand how we've gotten to this point, I think we're at risk of ignoring potentially more robust solutions. Rather than build up your application (or site) using a single monolithic JavaScript framework, I implore you to consider something that's a bit more open-web and future friendly: continuing to build with component-based architecture using all of the current tools available to you, and looking forward to use web components.
Before we get into why I think component-based architecture is the correct way for now, and web components are the way of the future, let's explore how we've gotten to where we are today.
It starts out innocently enough: you apply an ng-click attribute to a link or a button in your template. Then you add a couple of additional lines of markup to handle an if/else pattern to that template (<span ng-if="truthy"></span><span ng-if="falsy"></span> seem familiar?). Before you know it, you're applying ng-mouseover and writing custom directives to handle events specific to your markup.
Others might be looking at this and decide that it's lunacy to have all of that written by you, in-line in your template (and they're probably right -- if you're adding a lot of logic to your template, you probably need to reconsider what you're doing and approach the problem from a different angle). It's difficult to maintain, tightly couples your template to the controller logic behind it, and it's really not the template's job to manage complex logic.
However, rather than refactor to use unobtrusive JavaScript patterns or to extract out difficult logic so it's not present in the template, there's a push (primarily from the React project) to build everything up using JavaScript. Your logic (controllers, models, etc), your templates, and even your CSS. The thinking is, for the most part, that if you are doing these complicated decision trees in the code, then it should be handled by something designed to handle said complicated decision making.
For those who've been building websites and applications for long enough, seeing something that looks like this:
<div onMouseOver="{() => this.setState({ hover: true })} onMouseLeave="{() => this.setState({ hover: false })}" style={{borderColor: this.state.hover ? 'red' : 'transparent' }} />
...should remind you of nightmares of years past. This largely disregards the efforts of WASP (Zeldman, Meyer, Holzschlag, et al) and, more recently, the Web Standards Sherpa that lead the charge on making the web more maintainable (proper HTML markup, separation of style, content, and behavior) and future friendly. Additionally, we return to a state where the separation of concerns is being tossed out altogether and we're being asked to ignore years of learning in the favor or writing everything in JavaScript.
A typical React component would look something like this:
var buttonBase = { padding: 5, border: "1px solid #aaa", borderRadius: 5, backgroundColor: "#eee", };
var buttonBaseHover = _.defaults({ backgroundColor: "cyan", borderColor: "magenta", cursor: "pointer", }, buttonBase);
var BasicButton = React.createClass({ getDefaultProps: function() { return { type: "button", label: "Click me", }; }, getInitialState: function() { return { isHovering: false, }; }, propTypes: { type: React.PropTypes.string.isRequired, label: React.PropTypes.string, }, handleMouseOver: function() { this.setState({isHovering: true }); }, handleMouseOut: function() { this.setState({isHovering: false }); }, render: function() { return ( <button type={this.props.type} style={this.state.isHovering ? buttonBaseHover : buttonBase} onMouseOver={this.handleMouseOver} onMouseOut={this.handleMouseOut} > {this.props.label} </button> ); } });
React.render(<BasicButton label="Demo Button" />, document.getElementById('container'));
See the Pen React Button Component by Mike Tierney (@miketierney) on CodePen.
While this has the merits of being transportable (one of the better arguments for this style of development), it lends itself to higher maintenance issues. Like the common complaint of CSS, this is the sort of thing that quickly ends up creating bloat - it's easy to envision a scenario where a "BasicButton1" gets added because a developer is uncertain about making changes to it. While conditionals could be added to the render method, you then have added processing impact on whether or how to render the button. Many developers will make the same mistake here that they do with CSS: "I don't know where this is used, so I'll just make a copy of it, modify it, and use that in my implementation." Both are signs of maintenance issues, and both can be addressed with proper processes and practices (like code reviews).
If we move towards using One Tool For All Jobs (in this instance, JavaScript), we neglect the fact that the tools we're abandoning are actually quite good at doing what they need to do. CSS does a great many of the things that are related to styles far better than JavaScript and it has the added benefit of being cacheable, leveraging readily available resources (rather than littering your JS scope with event handlers for every element that needs to support interactivity; that can impact performance pretty heavily), and with proper use of the cascade you can more easily create variant styles as needed (site theming as a whole, for example).
To handle that hover effect from earlier in the post, you'd need to do this:
<div class="hover-div"/>
.hover-div:hover, .hover-div:focus { border-color: red; }
I've also added the :focus pseudo-class so we also have keyboard support. It'd take more than that to add that same support into that inline sample, and you're providing better support for your users. :focus is a relatively small thing by itself, but think about the broader implications. A natural byproduct of this is to rebuild native components. As an example, we're already rebuilding the select menu (because it's too hard to style natively), and that's just the start of a slippery slope. This should not be the norm - rebuilding existing browser components and behaviors in pure JavaScript might seem appealing (because you have total control over what it does, more or less), but the overhead of creating it in the first place is inevitably going to be greater than anticipated, and then you have to take into consideration the fact that you now have to maintain that. Furthermore, you now have to accommodate all current and future interaction patterns, UX experiences, and many other OS-level features that users are already familiar with in order to make your fancy widget not seem out of place. Is it really worth that? Do you really need (or have) that level of control? Why would you want to abandon future improvements that will roll out as browsers and standards improve? Finally, on this particular point, you'll also need to factor in support for assistive technologies. Just because you're building a "web app" doesn't mean you get a free pass to just ignore those users.
Many of the proponents of using this all-in-javascript approach are focused solely on making sure that everything is managed locally (as opposed to globally, which is how CSS operates). They neatly solve this "pollution" of the global space by injecting all of the styles directly on the element being styled, which is truly the only way to avoid that issue. However, this comes at a cost -- more complex elements can potentially have a significant number of style selectors (and let's be honest here, we're still using CSS whether it's in the DOM or in a dedicated stylesheet). This leads to greater DOM bloat, and more re-draws of elements within a page when states change, content is updated, or the initial view is rendered. While these things may not impact the immediate load time of the page, there's an overall impact on page rendering because of this. CSS isn't free of this, certainly, but one advantage of loading those files once is that this is minimized. Additionally, for things like layout and global styles, you want to have a more global take on things. For re-usable components (buttons, form elements, links) - why make the browser evaluate and render style for every element one at a time when you can pre-load the styles into memory and when a node appears that matches the selector, the styles will be applied.
My counter-proposal would be to use one of the better trends we've seen lately: component based architecture. Build small to large - much like the members of the React team who are advocating for using CSS in the JavaScript application want to do. This can be done with traditional techniques, however, and diligence to fending off entropy and bad practices. With tools like Sass and Less, we have the ability to create small files that are focused purely on building out a single component, which can then be stitched into the larger application as whole. When building a single page application, we can even start using an approach where our JS, HTML, and CSS all live together in the same directory, to later be concatenated,minified, and then moved into the appropriate locations. With a reasonable application of namespacing in CSS (pick your poison; I'm partial to SMACSS), we can accomplish the same goals - re-usable, easy to maintain, components - without jamming everything in to JavaScript.
Right now, I think a compromise is a mix of global and local styling. I still think styles added directly to DOM nodes is a mistake (with some exceptions -- an argument can be made for inlining styles on canvas/svg-based charts, for example, and I'm sure there are other situations, but those should be the exception and not the rule). We should think about making our components themable as much as possible, re-using tools that are available to us (the Cascade naturally supports this sort of behavior), and embrace the fact that we never have 100% control over the way our web-based application will look and behave. There are simply too many variables that are out of our control.
If you're concerned that your team is too large and you cannot communicate some of these practices widely, there are plenty of tools available to look for unused CSS, duplicate CSS, "bad" CSS, and inefficient selectors. These can be integrated in to your build process or development flow, depending on your preference.
One final point to make here is that we need to ensure that we are optimizing for our users. When we make the browser do all of the work for us because it makes maintaining a code-base easier, that's fine up to a point, but we need to be mindful of the overall impact that that has on the experience of the end-user. This also means, rather uncomfortably, that we (as developers) need to embrace that there are a great many things that are out of our control, and we should build our solutions to be as flexible as possible. Otherwise, we'd still just be building it all using Flash.
Additional recommended reading:
Regardless of industry, staff size, and budget, many of today’s organizations have one thing in common: they’re demanding the best content management systems (CMS) to build their websites on. With requirement lists that can range from 10 to 100 features, an already short list of “best CMS options” shrinks even further once “user-friendly”, “rapidly-deployable”, and “cost-effective” are added to the list.
There is one CMS, though, that not only meets the core criteria of ease-of-use, reasonable pricing, and flexibility, but a long list of other valuable features, too: Drupal.
With Drupal, both developers and non-developer admins can deploy a long list of robust functionalities right out-of-the-box. This powerful, open source CMS allows for easy content creation and editing, as well as seamless integration with numerous 3rd party platforms (including social media and e-commerce). Drupal is highly scalable, cloud-friendly, and highly intuitive. Did we mention it’s effectively priced, too?
In the final installment of our “Why Drupal?” 3-part series, we’re highlighting a few more features (many which you know you need, and others which you may not have even considered) that make Drupal a clear front-runner in the CMS market.
For a personalized synopsis of how your organization’s site can be built on or migrated to Drupal with amazing results, grab a free ticket to Drupal GovCon 2015 where you can speak with one of our site migration experts for free, or contact us through our website.
_____
User Permissions:
Right out of the box, Drupal gives you the ability to create unlimited roles and then assign one or more roles to the users. Permissions are given to each role, and are very granular: the granularity can even be applied down to the field level with contrib modules. The framework for developing new permissions is robust but very easy to implement.
Content Revisioning:
Another core Drupal feature that can be enabled per content type is content revisioning. Conversely, it can be disabled if the site needs to remain lean. One great feature is the contrib module that supports side-by-side comparisons between revisions.
Multi-Language:
Though multi-language translation is is not a core feature, there is a suite of mature and actively developed contrib modules that include integration with various automated translation services.
WYSIWYG:
While most CMS products have a WYSIWYG editor, Drupal does not have one out-of-the-box. This is intentional, however, because there is a contrib module that allows you to integrate with one or more editors. In fact, there are over 10 to choose from: https://www.drupal.org/node/596966
Galleries/Slideshows:
There are dozens of image gallery and slideshow modules for Drupal. Slides can be a custom content type so that the site is not just limited to images. Fieldable slides (i.e. thumbnail, title, description, etc.) can also be created. Most slideshow modules also include various display functionality, including sleek transition options.
Community:
With over 100,000 members on Drupal.org, Drupal boasts one of the strongest open source communities. As evidenced by the forums, collaboration is heavily emphasized. Members and developers are generally very helpful, and both groups welcome input as well as code contribution.
Example Sites Using Drupal:
https://www.drupal.org/case-studies
Other Resources:
https://www.acquia.com/sites/default/files/collateral/drupal-10-reasons_0.pdf
Want to know other amazing functionalities that Drupal has to offer? Contact us through Mobomo.com to speak with one of our Drupal gurus!
With Drupal, both developers and non-developer admins can deploy a long list of robust functionalities right out-of-the-box. This powerful, open source CMS allows for easy content creation and editing, as well as seamless integration with numerous 3rd party platforms (including social media and e-commerce). Drupal is highly scalable, cloud-friendly, and highly intuitive. Did we mention it’s effectively-priced, too?
In our “Why Drupal?” 3-part series, we’ll highlight some features (many which you know you need, and others which you may not have even considered) that make Drupal a clear front-runner in the CMS market.
For a personalized synopsis of how your organization’s site can be built on or migrated to Drupal with amazing results, grab a free ticket to Drupal GovCon 2015 where you can speak with one of our site migration experts for free, or contact us through our website.
_______________________________
SEO + Social Networking:
Unlike other content software, Drupal does not get in the way of SEO or social networking. By using a properly built theme--as well as add-on modules--a highly optimized site can be created. There are even modules that will provide an SEO checklist and monitor the site’s SEO performance. The Metatags module ensures continued support for the latest metatags used by various social networking sites when content is shared from Drupal.
E-Commerce:
Drupal Commerce is an excellent e-commerce platform that uses Drupal’s native information architecture features. One can easily add desired fields to products and orders without having to write any code. There are numerous add-on modules for reports, order workflows, shipping calculators, payment processors, and other commerce-based tools.
Search:
Drupal’s native search functionality is strong. There is also a Search API module that allows site managers to build custom search widgets with layered search capabilities. Additionally, there are modules that enable integration of third-party search engines, such as Google Search Appliance and Apache Solr.
Third-Party Integration:
Drupal not only allows for the integration of search engines, but a long list of other tools, too. The Feeds module allows Drupal to consume structured data (for example, .xml and .json) from various sources. The consumed content can be manipulated and presented just like content that is created natively in Drupal. Content can also be exposed through a RESTful API using the Services module. The format and structure of the exposed content is also highly configurable, and requires no programming.
Taxonomy + Tagging:
Taxonomy and tagging are core Drupal features. The ability to create categories (dubbed “vocabularies” by Drupal) and then create unlimited terms within that vocabulary is connected to the platform’s robust information architecture. To make taxonomy even easier, Drupal even provides a drag-n-drop interface to organize the terms into a hierarchy, if needed. Content managers are able to use vocabularies for various functions, eliminating the need to replicate efforts. For example, a vocabulary could be used for both content tagging and making complex drop-down lists and user groups, or even building a menu structure.
Workflows:
There are a few contributor modules that provide workflow functionality in Drupal. They all provide common functionality along with unique features for various use cases. The most popular options are Maestro and Workbench.
Security:
Drupal has a dedicated security team that is very quick to react to vulnerabilities that are found in Drupal core as well as contributed modules. If a security issue is found within a contrib module, the security team will notify the module maintainer and give them a deadline to fix it. If the module does not get fixed by the deadline, the security team will issue an advisory recommending that the module be disabled, and will also classify the module as unsupported.
Cloud, Scalability, and Performance:
Drupal’s architecture makes it incredibly “cloud friendly”. It is easy to create a Drupal site that can be setup to auto-scale (i.e., add more servers during peak traffic times and shut them down when not needed). Some modules integrate with cloud storage such as S3. Further, Drupal is built for caching. By default, Drupal caches content in the database for quick delivery; support for other caching mechanisms (such as Memcache) can be added to make the caching lightning fast.
Multi-Site Deployments:
Drupal is architected to allow for multiple sites to share a single codebase. This feature is built-in and, unlike Wordpress, it does not require any cumbersome add-ons. This can be a tremendous benefit for customers who want to have multiple sites that share similar functionality. There are few--if any--limitations to a multi-site configuration. Each site can have its own modules and themes that are completely separate from the customer’s other sites.
Want to know other amazing functionalities that Drupal has to offer? Stay tuned for the final installment of our 3-part “Why Drupal?” series!