Archives

All posts for the month August, 2013

marquee-product

Google has released their own competitor to Apple TV and Roku called Chromecast.  It’s a very small device that plugs into an HDMI port in your TV and can stream Internet video right to your TV.  The box is very small and does not come with a remote because your tablet/smart phone/laptop/desktop is your remote.  Using the apps on your tablet or smart phone you can stream YouTube videos, Google Play purchases, and Netflix to your TV with the push of a button.  For the desktop/laptop you can stream anything that is in your Google Chrome browser, which you should all be using anyway.  At a price tag of $35 it’s pretty easy to convince yourself to just jump in.  Below is the unboxing as well as my thoughts on setup and use.  I’ve had it for a few days now so I’m not a huge expert on it but it’s so simple there really isn’t much to it.

Let’s walk through the pictures and setup.  That small box is all you get when you order Chromecast.  Opening it up reveals the HDMI device and taking that out shows you there is at least one more wire.  Chromecast needs power, as HDMI ports aren’t powered, and it gets it through either a USB port on your TV, which is what I did, or they have an adapter that lets you plug it into a wall.  After plugging it in you switch to the HDMI channel for that device and you see that great setup screen.  It tells you the URL to go to and you follow the very basic setup instructions.  As anyone who knows me will attest, I tend to skip instructions and I misread what I was supposed to do.  It said to connect to the Chromecast’s WiFi using my phone or laptop.  I thought it meant the WiFi my Chromecast will be on, hence the error screen.  Once I reread and then checked the available networks I saw my Chromecast was broadcasting and let me jump on.  After connecting you go through a setup to verify that it is installed correctly and to tell Chromecast which network to connect to, give the WiFi password, and give your Chromecast a name!  I named mine Chrometastic.  It took a couple of tries to initially connect to my network but once it was connected everything was great.

Until I released there really isn’t that much to do with Chromecast right now.  There are only a very small handful of native apps that will stream to the Chromecast.  Right now only YouTube, Google Play, and Netflix work natively with big names like Hulu, HBO, Redbox Instant, and Revision 3 among others working on apps to be released soon.  We don’t use Netflix, we use Amazon Prime Instant Video, so that’s one app I don’t use and I’ve never bought anything from the Play Store, though I may now.  YouTube I have never really been into either.  I know there are people who can watch hours of YouTube but I never saw the appeal, until now.  Using my Nexus 10 I setup a queue of YouTube videos that lasted two hours and just sat and watched all the goofy things that are on YouTube.  Very easy to use and the quality on the screen is perfect.

The Hulu app is still in development but I wanted to try streaming from my laptop to the screen using Chrome.  I opened up Chrome, downloaded the extension, and headed over to Hulu.  I picked a great episode of Psych to see how good the quality would be and hit the Cast button.  After a moment of buffering that tab appeared on the TV, video and all.  The frame rate was a bit lower than the native apps but it was definitely not terrible.  They say that feature is still in beta, what Google product isn’t?, so I hope it gets a little better but it’s not bad at all.

There has been talk of Google blocking you from playing local content through Chromecast.  This was a huge bummer to me because that is one of the things I wanted to do with it.  Luckily, just as I was writing this, Google has come out and said that they will let you cast content from your local storage.  Big plus and I’m glad they said something about it.

I loved everything about the experience and continue to use it as my YouTube watching device.  I think it is still really new and needs to be developed a bit more but is worth $35.  Once more apps are created for it, really looking at you Amazon, it will be awesome.  Even though I know everyone already has a device that plays digital media like a Playstation 3, XBox 360, Apple TV, Roku, the list goes on, I think there is a place for Chromecast if only for the price and YouTube watching.

urls

With so many templates in a large project that all link together in creative and complicated ways it can be a pain to keep track of URLs.  Every URL is an address that can also have a number of variables associated with it.  If these need to be changed it can be very tedious to go through every file and replace the hard-coded URLs to reflect the change.  Helping with this, Django has a template feature that will look those URLs up for you and insert the relative URL, without the domain name, into your templates on render.

It’s a waste to have hard-coded URLs in your templates and if you are adhering to the DRY principle, don’t repeat yourself, you’ll not want to have the same hard-coded URL in many places in the same project.  Using the {% url %} tag you can reference a view and no matter what its URL is Django will handle it for you.

Example time:

urls.py

views.py

base.html

This application, Marketing, uses a base.html page that is extended in all sub pages.  This gives the ability to have the same menu across all pages in the app.  I also limit the links based on whether a customer has been selected or not.  Let’s focus on the url tags though.  In the menu we see there are three links; marketing home, overview, and profile.  The first url tag demonstrates the most basic use of the Django url tag.  Simply it in your href and you have a link.  Make sure to have quotations around the view you are referencing, this was an update starting with Django 1.5.

Some URLs take parameters and we will need to pass those on occasion.  This is very easy to do by putting a space after the view and then adding the parameters, in order, with spaces between them.  If you don’t want to use the default ordering of the URL you can call out the variable name in the url tag.  Changing the marketing overview link to use the named parameter it would change to {% url "marketing.views.overview" cus_id=customer.customer_number %}.  Simple enough, right?  You can even reference views used outside of the immediate app like I have done with the Profile link that moves you to the customers application.  Django will handle all of your URL needs.

Hope this clears up how to leverage this great tool from Django.  I know when I first started with Django I didn’t use this as much as I should have but I’m loving it now.

Bootstrap 3 Released

Just a quick note for everyone, Bootstrap has officially released version 3.0.0 as of Monday.  If you have been following along with the blog so far you’ll already be familiar with the major changes to Bootstrap.  This final release fixes a lot of those bugs that I’ve brought up here.  It is now stable and ready for production.  The biggest complaint I’ve seen from people is the move to the flat theme by default where the 2.3.2 version was polished and looked nice.  The good news is that Bootstrap allows you to use the new version with the old look, problem solved!  We are going to continue with the flat look because we like it but it’s totally up to you how you use Bootstrap.  Full release notes here.  Good luck!

Screenshot from 2013-08-22 09:04:36

Sometimes it’s necessary to display a message to the user in a quiet and clean manner.  To do this, Django has given us the messages framework for cookie- and session-based messaging.  After a form or other input is submitted we can quickly send a short message to the user without much effort at all.  Here are all the documents related to the framework but I’m going to give you the quick version as well as some customization options and Bootstrap fixes.

The messaging framework is enabled by default when you create a new Django project so good job you’re half way there!  Now just add this bit of code to the top of any page you want messages to appear:

We have this in our base that is inherited by every page to allow the functionality to appear on the entire site.  You need to have the loop even if you only have one message because it helps clear the message storage needs to be cleared.  Now the great thing is you don’t need to return messages when you render your template it will just come with it because of the context processor involved.

To add messages to your page, in your view:

That’s it!  You just have to have the line messages.add_message(request, MESSAGE_TYPE, MESSAGE_STRING) and then use the context_instance in your render and you’re done.

Bootstrap Compatability

To use this with Bootstrap you need to leverage the message.tags dictionary that returns values for each of the message levels.  Here is our code that we use for messages in our Bootstrap site.

As you can see we surround the message in an alert class with an alert-{{ message.tags }} class and add the Bootstrap close button.  This works out of the box for all Django messages except messages.ERROR.  This is because messages.ERROR returns ‘error’ which will make the alert class alert-error which is not what Bootstrap uses, they use alert-danger.  To fix this, as well as add new message types, you need to alter your settings file by adding this variable:

The import just above the line helps to avoid circular imports.  At this point you can see that we have changed the constant for messages.ERROR to return ‘danger’ instead of ‘error’.  This fixes our Bootstrap problem but you can see that now you can add new message constants not already created like messages.AWESOME or whatever else you’d like to make.

There is a lot more to the Django messages framework including error levels that I didn’t get into here.  Check out their docs for the low down on all the different things you can do with Django messages.

Here is a screenshot of an example I did just to test things out.

Screenshot from 2013-08-22 09:09:47

menu-title

Designing our new internal marketing tools has been a pet project of mine for a couple of weeks now.  I spend a little time here and there adding information and tools for our employees to better understand our relationship with our clients.  I’m displaying basic contact information, some information on the kind of business we do with them, a log of notes we take, past business, and company information.  All of that equates to a rather long page of information.  All of the information is relevant and displayed in an attractive compact manner the problem is it is just so much information that it can be overwhelming.  I showed it to a coworker and he wanted tabs to flip between the various bits of information because he found it overwhelming.  I didn’t want to go to tabs because of the increased difficulty that would be added when they wanted to print off the marketing information and I didn’t feel that tabs were the right way to go here.  With that in mind I needed another solution for a large page of information that could be easily navigable…enter Bootstrap ScrollSpy.

Anyone who has looked at the Bootstrap documentation will immediately notice that has exactly the same problem I’m having; long page with lots of information.  On the left they have a static menu that follows you and highlights what section you are currently in.  Clicking on any one of those links will bring you to that portion of the page.  If it’s good enough for them it’s good enough for me so I set about recreating their side menu style.

ScrollSpy can be used with any .nav menu whether it is one your create with a ul or if it is the main nav-bar at the top of the screen.  ScrollSpy works by checking what element is currently at the top of the visible screen and adding making that nav element active.  This is great but there are a few quirks and tweeks that took me a while to figure out.

At the most basic level you want to add the HTML 5 data-spy attribute to your body because that is what we are going to spy on.  Here is the example code from Bootstrap’s documentation.

The data-target attribute needs to point to the parent element of your nav.  So if you have a nav-bar you’ll need to have an outer div or element with the id that you will use in your ScrollSpy.

Now all of your elements in your nav will need to have an href pointing to the id of the element you will be spying on.  These will need to be valid elements in your DOM.  If you are adding things dynamically and need to update your ScrollSpy use

That’s it for the simple example.  Set the data-spy and data-target on your body tag and you should be all set assuming your nav is set up properly.  One issue you may run into is not spying on the body.  When I originally started this I wasn’t spying on the body tag because I was loading in a template using Django’s block tags.  Granted it was within the body tag at one point but not specifically and I wanted to only watch my div.  ScrollSpy will only work correctly on non-body tag elements if they have a fixed height and a scroll bar.  If you do not have a scroll bar on the element you are spying on it will not work.  Your nav-bar will always have the last element as active.  To fix this just give the element you are spying on a fixed height and you should be good.  In my case instead of using the HTML 5 tags on the body I used JavaScript.  The body tag is used in every page and I didn’t want the ScrollSpy loaded on every single page.  In my JavaScript for my marketing page I have the line $("body").scrollspy({target: "#side-nav", offset:50});.  The offset tells ScrollSpy by how many pixels to offset the scroll before we are actually “in” the element.  I added some padding so when you see the header near the top we are now in the section.

To mimic the fixed sidebar used on the Bootstrap documentation use either the Affix JavaScript from Bootstrap or the affix class on your nav.  Below I have my full example and how it all works.

HTML

 JavaScript

I hide the side nav on smaller resolutions to give more screen real estate. The a tags have both a name and an id because the id is used by ScrollSpy and the name is used as a normal locator on a page.  Let me know what you think and if there are any questions or comments.

As Bootstrap nears releasing their final version of Bootstrap 3 they will continue to roll out Release Candidates for bug fixing and testing.  We have elected to keep as up to date with them as we can under the assumption that release candidates are fairly stable and shouldn’t change too much between now and release.  Tuesday they released their next release candidate, RC2.  You can read about the full changes at their blog but I’m going to highlight a few of the main things that changed for us.

Default Col is Gone

In RC1 we were using col- to be the default size for all devices.  RC2 has removed this default class.  Instead they have added a new -xs size for really small phones and a -md, though I think this was in RC1 we just never used it.  The best way to do a default size for most devices is now to use to col-sm-.  Use the small version because it works for devices with a screen resolution  of ≥768px.  This is what most modern devices are using.  Anything lower than that will default your spans to be like a col-12.  If you need to make changes for screens smaller than that use col-xs-.

Navbar Changes

Some little things changed with the navbar.  Just quick changes to classes.  You’ll need to wrap the mobile navbar header in a div with the class navbar-header.  Change nav-collapse to navbar-collapse.

Large and Small or lg and sm?

To keep consistency throughout Bootstrap they have changed many of the button classes from button-large to button-lg and button-small to button-sm. Form groups is also affected by this change.

Those are some of the main things we found.  I’m sure there are plenty of things that are affecting other people.  Head over to their blog to read all about it.  I’ll update this post if I come across anything else.

EDIT Aug 16 12:06PM

It seems we’ve stumbled upon a bug in their Modal.  When a modal is opened and then closed when you reopen it you can’t close it with the x or the close button. They are aware of the issue.  Our modals are actually all out of whack and we are looking into that right now which is how we found that bug.

EDIT Aug 16 12:20PM

Modals loaded remotely are being loaded into the modal and not the modal-body.  To fix this just move all of the divs below the modal into your remote document and that should work for now.  It’s an issue they are discussing.

EDIT Aug 19 1:01PM

When you print it uses the col-xs tag.  Make sure to update accordingly.

typeaheadjs

 

New Version – Twitter Typehead.js v0.10

Bootstrap dropped support for their bootstrap-typeahead.js and suggested we all use Twitter’s Typeahead.js.  This was a pretty big change for us and we encountered a bit of a learning curve because the documentation wasn’t exactly what we had hoped it would be.  Typeahead.js is incredible and can do some amazing things though and we are happy to be using it.

The first issue is that right out of the box it will not work with Bootstrap 3.  Support is still being looked at but in the mean time there are some fixes.  Here is a thread about the issue on their GitHub page with some helpful people posting solutions for the interim.  Below is the code we are using for ours which I’m sure will change in the coming days.

Once we got the formatting and could create our typeahead inputs we needed data for them.  We were using AJAX calls to our server to get the list as the user typed.  This worked but was a little slow.  Typeahead now has a few different ways of populating data into the input field.

Local

Local is a list of hard coded values right in your JavaScript

Prefetch

When the page is loaded the ajax call is made and stored in the browser’s local storage so the next time you visit the page it does not need to make another request unless the time-to-live has expired.  The ttl is defaulted to one day but you can change that in the options you pass.  One thing to note is that your browser has a limited amount of storage for this type of thing.  When we tried to pull our contacts list all in one go it would crash typeahead because the browser ran out of memory for local storage.  Our fix for this was that the prefetch URL would only return a limited number of entries, for example, the last 1000 updated contacts.

Remote

If the user starts to try and type something that isn’t immediately available through prefetch or local it falls back to your remote URL.  Just place the %QUERY tag in your URL and it will take what the user has entered and make a call to your server for a list using that query.

Full Example:

Templates

Typeahead supports your own custom templates for the drop down.  In our case we are just making the customer number bold and displaying their name but you could do everything from changing fonts, making inline lists, or even displaying images inline with your results.  Very cool.

Datums

We learned the hard way about a few different things when formatting results for your typeahead.  Typeahead expects a list of dictionaries with certain values, these are called datums.  Only two keys are required by typeahead, value and tokens.  After that you can add your own keys to be used by the typeahead for whatever purpose you’d like, whether it’s changing what happens on click or an image to be placed inline.  The value is the actual value of the typeahead, what the user is trying to get to.  Tokens are a list of strings that help the user get to where they want to go.  One very important note, the tokens must be single word strings — no spaces.   Spaces come across as %20 and when the user enters a normal space the typeahead doesn’t recognize that correctly.  So what we did was split the name of the company/contact into a list of separate strings for each word and that worked great.

Onward

Still playing around with it but I feel like we have a pretty good grasp on it.  Here is a list of their examples just to help drive the point home a bit further. Just waiting on the Bootstrap 3 support but overall we are happy with the new typeahead after we spent a long time trying to figure out all of the quirks we were having with it.

Hope this is helpful to others out there.

EDIT 16 September 2013

Some people were complaining about the dropdown not dynamically scaling.  Git user karimlahlou has posted this to fix that problem.

Thank you @ashleydw, finally i got it working. for those need to adjust the list width, use this function:

Hope this helps a few people.