SlideShare a Scribd company logo
Tips & Tricks for Front End Development AutomationEvan Reiser
Front End Automation?Tools / Tricks to speed up front end dev workWhy talk about this?Same reason we all like Django:More time solving our biz/eng problemsLess time doing the same repeatable patternsWe want to: Build web apps + add featuresNot: waste time deploying media, organizing assets, minifying js/css, making sprites etc.
django experienceCo-founder @ GamerNookSocial Network for Gamers100k+ MembersCo-founder @ BloomSpotLuxury Daily Deals3rd Largest Daily Deals siteCo-founder @ AdStackAlgorithmically Managed Facebook Advertising
OverviewPains with Front end DevelopmentDeploying Media FilesCompressing / Combine media filesGenerating SpritesAutomate all of this
Problems / PainsAnnoying parts of front end developmentDeploying media to media server / CDNCombining JS / CSS filesMinimizing JS / CSSCache-busting media files in prodBuilding sprite imagesReferencing sprites in CSSHaving to do this all manuallyThese are all common patternsWe shouldn’t have to waste time on them
Toolsdjango.contrib.staticfilesdjango_storagesbotodjango_compressorYUI JS/CSS Compressordjango_media_bundlerPILpngcrush
django.contrib.staticfilesPulls media from various placesPlaces them in another placeDifferent folderMedia ServerOr any custom storage backendS3 / CloudFrontCDN
Media Files => CDN1) Set up static files to find #settings.pySTATICFILES_DIRS = (os.path.join(os.getcwd(),"media"),    )STATICFILES_FINDERS = (    'django.contrib.staticfiles.finders.FileSystemFinder',    'django.contrib.staticfiles.finders.AppDirectoriesFinder',)STATIC_ROOT = os.path.join(os.getcwd(),"static")
Media Files => CDN	2) Set Storage backend to be S3 / CloudFront#settings.pySTATICFILES_STORAGE = 'storages.backends.s3boto.S3BotoStorage 'boto
Is a python library for interacting with Amazon Web Services
django_storages
A series of storage backends including  a S3Media Files => CDN2) Push media files to CDNpython manage.py collectstatic
Media Files => CDN	4) Reference media in your templates#settings.pyTEMPLATE_CONTEXT_PROCESSORS += (    'django.core.context_processors.static',){# Some Template #}<link rel="stylesheet" href="{{STATIC_URL}}style.css" /><link rel="stylesheet" href=“http://cdn.adstack.com/style.css" />
 Managing MediaManaging MediaCSS / JavaScript assetsWe want to:Reduce Http requestsReduce bandwidthWe don’t want to:Think about front-end performance while codingInterrupt our development
 Managing Media1. We want to reduce the number of HTTP requests for serving JS + CSS<link rel="stylesheet" href="{{STATIC_URL}}css/admin/base.css" /><link rel="stylesheet" href="{{STATIC_URL}}css/admin/changelists.css" /><link rel="stylesheet" href="{{STATIC_URL}}css/icon_sprites.css"/><link rel="stylesheet" href="{{STATIC_URL}}css/common_10.css" /><link rel="stylesheet" href="{{STATIC_URL}}css/tablesorter.css" /><link rel="stylesheet" href="{{STATIC_URL}}css/multiselect.css" /><link rel="stylesheet" href="{{STATIC_URL}}css/superfish.css" /><link rel="stylesheet" href="{{STATIC_URL}}css/all.css" />
 Managing Media2. We want to minify css / js content and only include what’s needed (reduce bandwidth)/*   Make sure to rename this file before you deploy to break client caching!!!*//* Headers */H1 { font-weight:bold;}H2 {font-weight;bold;}H1,H2 {font-weight:bold}Obviously the same thing goes for JS
 Managing Media3. Don’t want to have to change the asset names to prevent client side cachingStyle.cssStyle2.cssStyle3.cssStyle4.cssStyle5.css
 Managing MediaOne way to do this is django_compressorConverts & combines linked or inline css/js into cacheable static filesCompression / minification support for: CSS Tidy, YUI CSS + JS, Google’s Closure Compiler, JSmin, cssminBuilds unique static file names to bust cacheNo need to heavily modify existing templatesPlus:Extendable for custom post processing / filtering via python
 Managing MediaTemplate changes are minimal{% compress css %}<link href="{{STATIC_URL}}css/admin/base.css" /><link href="{{STATIC_URL}}css/admin/changelists.css" /><link href="{{STATIC_URL}}css/icon_sprites.css"/><link href="{{STATIC_URL}}css/common_10.css" /><link href="{{STATIC_URL}}css/tablesorter.css" /><link href="{{STATIC_URL}}css/multiselect.css" /><link href="{{STATIC_URL}}css/superfish.css" />{% endcompress %}{%  compress js %}<script src="{{STATIC_URL}}js/jquery-1.5.1.min.js"></script><script src="{{ STATIC_URL }}js/jquery.hoverIntent.js"></script><script src="{{STATIC_URL}}js/common.js"></script><script src="{{STATIC_URL}}js/jquery.multiselect.min.js"></script><script src="{{STATIC_URL}}js/jquery.cluetip.min.js"></script><script src="{{STATIC_URL}}js/jquery.tablesorter.js"></script><script src="{{ STATIC_URL }}js/jquery.tooltip.pack.js"></script><script src="{{ STATIC_URL }}js/superfish.js"></script>{%  endcompress %}
Compressor SettingsWe use a custom Storage Class to store the results on S3from django.core.files.storage import get_storage_classfrom storages.backends.s3boto import S3BotoStorage #A special Storage class that saves to S3 and Locallyclass CachedS3BotoStorage(S3BotoStorage):       def __init__(self, *args, **kwargs):        super(CachedS3BotoStorage, self).__init__(*args, **kwargs)        self.local_storage = get_storage_class(            "compressor.storage.CompressorFileStorage")()     def save(self, name, content):        name = super(CachedS3BotoStorage, self).save(name,content)        self.local_storage._save(name, content)        return name
Compressor SettingsCompressor settings for offline / pre-grenerationimport osSTATICFILES_FINDERS += (    'compressor.finders.CompressorFinder',)COMPRESS_OFFLINE = TrueCOMPRESS_STORAGE = "common.common_storages.CachedS3BotoStorage"COMPRESS_ROOT = os.path.join(os.path.dirname(__file__), 'media')COMPRESS_OUTPUT_DIR = "compress_cache"COMPRESS_OFFLINE_CONTEXT = {"STATIC_URL":STATIC_URL}COMPRESS_URL = STATIC_URL #post processing filtersCOMPRESS_CSS_FILTERS = ['compressor.filters.yui.YUICSSFilter‘]COMPRESS_JS_FILTERS = ['compressor.filters.jsmin.JSMinFilter']COMPRESS_YUI_BINARY = 'java -jar %s yuicompressor-2.4.6.jar'
 Managing Mediapython manage.py compresscombines  static content
applies post processing filters
creates unique name from hash of content
pushes to S3/CDN Managing MediaWhen template rendersContent is hashed => hash value stored in cacheIndividual reference in template replaced{% compress css %}<link href="{{STATIC_URL}}css/admin/base.css" /><link href="{{STATIC_URL}}css/admin/changelists.css" /><link href="{{STATIC_URL}}css/icon_sprites.css"/><link href="{{STATIC_URL}}css/common_10.css" /><link href="{{STATIC_URL}}css/tablesorter.css" /><link href="{{STATIC_URL}}css/multiselect.css" /><link href="{{STATIC_URL}}css/superfish.css" />{% endcompress %}<link rel="stylesheet" href="http://cdn.adstack.com/compress_cache/css/32dd63bd423c.css" />
Automatic SpritesWhat are sprites?Sprites are composite images    made up of other imagesWhy?Reduce # HTTP requestsHow?CSS is used to only show part of the composite image
Automatic SpritesHow do we use sprites?Set them as a css background on a fixed size elementPosition them so only   part of the larger   image showsCool.But this is really a painCreating imagesCustom css for positioning
Automatic Spritesdjango_media_bundler
can help build the sprite automatically
Generates positioning CSS
Uses python + PIL to generate the sprite
Uses pngcrush to optimize the final image size
Use Case:

More Related Content

DOCX
Basic CSS concepts by naveen kumar veligeti
PDF
SEO dataLayer 2: Entity Wars
PDF
Lotusphere 2012 Speedgeeking - jQuery & Domino, a RAD Combination
PPT
Windows Vista
PPTX
Wordpress seo and digital marketing
PPT
How to use a blog for publishing scientific research: A training guide part 2
PPTX
Training HTML
PPT
Advanced SEO for Web Developers
Basic CSS concepts by naveen kumar veligeti
SEO dataLayer 2: Entity Wars
Lotusphere 2012 Speedgeeking - jQuery & Domino, a RAD Combination
Windows Vista
Wordpress seo and digital marketing
How to use a blog for publishing scientific research: A training guide part 2
Training HTML
Advanced SEO for Web Developers

What's hot (19)

PDF
Seo cheat sheet_2-2013
DOCX
ARTICULOENINGLES
PPTX
Seo for Engineers
PPTX
What's Next for Page Experience - SMX Next 2021 - Patrick Stox
PDF
Latency Kills by Shishir Birmiwal
PPTX
Social Media Workshop - Word Press
PDF
Blackhat Analyics 4: May the 25th be with you!
PPT
Joomla 1.6 Core SEO and Best Practices
PPT
Joomla 1.7 SEO
PPTX
Global SharePoint Users Group 1/5/10 - Creating Custom Actions Within SharePoint
PPTX
A Crash Course in Technical SEO from Patrick Stox - Beer & SEO Meetup May 2019
PDF
How can a data layer help my seo
PPT
BP304 - Blog It Up, Baby! Extending the new IBM Lotus Domino Blog Template
PDF
7 steps
PPTX
SharePoint Saturday Boston 2/27/10 - Whats New For Developers In SharePoint 2010
DOCX
Master page
PPTX
Advanced WordPress Optimization - iGaming Supershow 2012
PPTX
SharePoint Saturday Hartford - 01/29/11 - Creating Custom Actions in SharePoi...
DOCX
HTML Basics 2 workshop
Seo cheat sheet_2-2013
ARTICULOENINGLES
Seo for Engineers
What's Next for Page Experience - SMX Next 2021 - Patrick Stox
Latency Kills by Shishir Birmiwal
Social Media Workshop - Word Press
Blackhat Analyics 4: May the 25th be with you!
Joomla 1.6 Core SEO and Best Practices
Joomla 1.7 SEO
Global SharePoint Users Group 1/5/10 - Creating Custom Actions Within SharePoint
A Crash Course in Technical SEO from Patrick Stox - Beer & SEO Meetup May 2019
How can a data layer help my seo
BP304 - Blog It Up, Baby! Extending the new IBM Lotus Domino Blog Template
7 steps
SharePoint Saturday Boston 2/27/10 - Whats New For Developers In SharePoint 2010
Master page
Advanced WordPress Optimization - iGaming Supershow 2012
SharePoint Saturday Hartford - 01/29/11 - Creating Custom Actions in SharePoi...
HTML Basics 2 workshop
Ad

Similar to Font End Development + Automation with Django (20)

PPTX
Web Optimisation
PPT
Front End Website Optimization
PPT
performance.ppt
PDF
Website Performance Basics
PDF
Beyond Resizing: The Image Performance Checklist
ODP
Cms - Content Management System Utilities for Django
PDF
HyperLight Websites
PDF
A little journey into website optimization
PDF
Optimizing design: a UX practitioners guide
PDF
Optimizing static content in Django.pdf
PDF
Hyperlight Websites - Chris Zacharias
PPTX
A holistic approach to web performance
PDF
Front end performance (RailsWayCon 2009 short talk)
KEY
Faster Frontends
PPTX
EscConf - Deep Dive Frontend Optimization
PPT
Building Mobile Optimized Websites
PPT
“Building Mobile Optimized Websites,” Nick Bourgeois / Ray Villares
ODP
Web (UI) Development
PDF
Next Steps in Responsive Design
PDF
Monkeytalk Fall 2012 - Responsive Web Design
Web Optimisation
Front End Website Optimization
performance.ppt
Website Performance Basics
Beyond Resizing: The Image Performance Checklist
Cms - Content Management System Utilities for Django
HyperLight Websites
A little journey into website optimization
Optimizing design: a UX practitioners guide
Optimizing static content in Django.pdf
Hyperlight Websites - Chris Zacharias
A holistic approach to web performance
Front end performance (RailsWayCon 2009 short talk)
Faster Frontends
EscConf - Deep Dive Frontend Optimization
Building Mobile Optimized Websites
“Building Mobile Optimized Websites,” Nick Bourgeois / Ray Villares
Web (UI) Development
Next Steps in Responsive Design
Monkeytalk Fall 2012 - Responsive Web Design
Ad

Recently uploaded (20)

PPTX
Programs and apps: productivity, graphics, security and other tools
PDF
Encapsulation theory and applications.pdf
PDF
gpt5_lecture_notes_comprehensive_20250812015547.pdf
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PPTX
A Presentation on Artificial Intelligence
PDF
Empathic Computing: Creating Shared Understanding
PDF
NewMind AI Weekly Chronicles - August'25-Week II
PPTX
Spectroscopy.pptx food analysis technology
PDF
Spectral efficient network and resource selection model in 5G networks
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PDF
Network Security Unit 5.pdf for BCA BBA.
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PDF
Assigned Numbers - 2025 - Bluetooth® Document
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
Encapsulation_ Review paper, used for researhc scholars
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
Programs and apps: productivity, graphics, security and other tools
Encapsulation theory and applications.pdf
gpt5_lecture_notes_comprehensive_20250812015547.pdf
Mobile App Security Testing_ A Comprehensive Guide.pdf
“AI and Expert System Decision Support & Business Intelligence Systems”
The Rise and Fall of 3GPP – Time for a Sabbatical?
A Presentation on Artificial Intelligence
Empathic Computing: Creating Shared Understanding
NewMind AI Weekly Chronicles - August'25-Week II
Spectroscopy.pptx food analysis technology
Spectral efficient network and resource selection model in 5G networks
Building Integrated photovoltaic BIPV_UPV.pdf
Network Security Unit 5.pdf for BCA BBA.
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
Assigned Numbers - 2025 - Bluetooth® Document
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Encapsulation_ Review paper, used for researhc scholars
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Advanced methodologies resolving dimensionality complications for autism neur...
Build a system with the filesystem maintained by OSTree @ COSCUP 2025

Font End Development + Automation with Django

  • 1. Tips & Tricks for Front End Development AutomationEvan Reiser
  • 2. Front End Automation?Tools / Tricks to speed up front end dev workWhy talk about this?Same reason we all like Django:More time solving our biz/eng problemsLess time doing the same repeatable patternsWe want to: Build web apps + add featuresNot: waste time deploying media, organizing assets, minifying js/css, making sprites etc.
  • 3. django experienceCo-founder @ GamerNookSocial Network for Gamers100k+ MembersCo-founder @ BloomSpotLuxury Daily Deals3rd Largest Daily Deals siteCo-founder @ AdStackAlgorithmically Managed Facebook Advertising
  • 4. OverviewPains with Front end DevelopmentDeploying Media FilesCompressing / Combine media filesGenerating SpritesAutomate all of this
  • 5. Problems / PainsAnnoying parts of front end developmentDeploying media to media server / CDNCombining JS / CSS filesMinimizing JS / CSSCache-busting media files in prodBuilding sprite imagesReferencing sprites in CSSHaving to do this all manuallyThese are all common patternsWe shouldn’t have to waste time on them
  • 7. django.contrib.staticfilesPulls media from various placesPlaces them in another placeDifferent folderMedia ServerOr any custom storage backendS3 / CloudFrontCDN
  • 8. Media Files => CDN1) Set up static files to find #settings.pySTATICFILES_DIRS = (os.path.join(os.getcwd(),"media"), )STATICFILES_FINDERS = ( 'django.contrib.staticfiles.finders.FileSystemFinder', 'django.contrib.staticfiles.finders.AppDirectoriesFinder',)STATIC_ROOT = os.path.join(os.getcwd(),"static")
  • 9. Media Files => CDN 2) Set Storage backend to be S3 / CloudFront#settings.pySTATICFILES_STORAGE = 'storages.backends.s3boto.S3BotoStorage 'boto
  • 10. Is a python library for interacting with Amazon Web Services
  • 12. A series of storage backends including a S3Media Files => CDN2) Push media files to CDNpython manage.py collectstatic
  • 13. Media Files => CDN 4) Reference media in your templates#settings.pyTEMPLATE_CONTEXT_PROCESSORS += ( 'django.core.context_processors.static',){# Some Template #}<link rel="stylesheet" href="{{STATIC_URL}}style.css" /><link rel="stylesheet" href=“http://cdn.adstack.com/style.css" />
  • 14. Managing MediaManaging MediaCSS / JavaScript assetsWe want to:Reduce Http requestsReduce bandwidthWe don’t want to:Think about front-end performance while codingInterrupt our development
  • 15. Managing Media1. We want to reduce the number of HTTP requests for serving JS + CSS<link rel="stylesheet" href="{{STATIC_URL}}css/admin/base.css" /><link rel="stylesheet" href="{{STATIC_URL}}css/admin/changelists.css" /><link rel="stylesheet" href="{{STATIC_URL}}css/icon_sprites.css"/><link rel="stylesheet" href="{{STATIC_URL}}css/common_10.css" /><link rel="stylesheet" href="{{STATIC_URL}}css/tablesorter.css" /><link rel="stylesheet" href="{{STATIC_URL}}css/multiselect.css" /><link rel="stylesheet" href="{{STATIC_URL}}css/superfish.css" /><link rel="stylesheet" href="{{STATIC_URL}}css/all.css" />
  • 16. Managing Media2. We want to minify css / js content and only include what’s needed (reduce bandwidth)/* Make sure to rename this file before you deploy to break client caching!!!*//* Headers */H1 { font-weight:bold;}H2 {font-weight;bold;}H1,H2 {font-weight:bold}Obviously the same thing goes for JS
  • 17. Managing Media3. Don’t want to have to change the asset names to prevent client side cachingStyle.cssStyle2.cssStyle3.cssStyle4.cssStyle5.css
  • 18. Managing MediaOne way to do this is django_compressorConverts & combines linked or inline css/js into cacheable static filesCompression / minification support for: CSS Tidy, YUI CSS + JS, Google’s Closure Compiler, JSmin, cssminBuilds unique static file names to bust cacheNo need to heavily modify existing templatesPlus:Extendable for custom post processing / filtering via python
  • 19. Managing MediaTemplate changes are minimal{% compress css %}<link href="{{STATIC_URL}}css/admin/base.css" /><link href="{{STATIC_URL}}css/admin/changelists.css" /><link href="{{STATIC_URL}}css/icon_sprites.css"/><link href="{{STATIC_URL}}css/common_10.css" /><link href="{{STATIC_URL}}css/tablesorter.css" /><link href="{{STATIC_URL}}css/multiselect.css" /><link href="{{STATIC_URL}}css/superfish.css" />{% endcompress %}{% compress js %}<script src="{{STATIC_URL}}js/jquery-1.5.1.min.js"></script><script src="{{ STATIC_URL }}js/jquery.hoverIntent.js"></script><script src="{{STATIC_URL}}js/common.js"></script><script src="{{STATIC_URL}}js/jquery.multiselect.min.js"></script><script src="{{STATIC_URL}}js/jquery.cluetip.min.js"></script><script src="{{STATIC_URL}}js/jquery.tablesorter.js"></script><script src="{{ STATIC_URL }}js/jquery.tooltip.pack.js"></script><script src="{{ STATIC_URL }}js/superfish.js"></script>{% endcompress %}
  • 20. Compressor SettingsWe use a custom Storage Class to store the results on S3from django.core.files.storage import get_storage_classfrom storages.backends.s3boto import S3BotoStorage #A special Storage class that saves to S3 and Locallyclass CachedS3BotoStorage(S3BotoStorage):       def __init__(self, *args, **kwargs):        super(CachedS3BotoStorage, self).__init__(*args, **kwargs)        self.local_storage = get_storage_class(            "compressor.storage.CompressorFileStorage")()     def save(self, name, content):        name = super(CachedS3BotoStorage, self).save(name,content)        self.local_storage._save(name, content)        return name
  • 21. Compressor SettingsCompressor settings for offline / pre-grenerationimport osSTATICFILES_FINDERS += ( 'compressor.finders.CompressorFinder',)COMPRESS_OFFLINE = TrueCOMPRESS_STORAGE = "common.common_storages.CachedS3BotoStorage"COMPRESS_ROOT = os.path.join(os.path.dirname(__file__), 'media')COMPRESS_OUTPUT_DIR = "compress_cache"COMPRESS_OFFLINE_CONTEXT = {"STATIC_URL":STATIC_URL}COMPRESS_URL = STATIC_URL #post processing filtersCOMPRESS_CSS_FILTERS = ['compressor.filters.yui.YUICSSFilter‘]COMPRESS_JS_FILTERS = ['compressor.filters.jsmin.JSMinFilter']COMPRESS_YUI_BINARY = 'java -jar %s yuicompressor-2.4.6.jar'
  • 22. Managing Mediapython manage.py compresscombines static content
  • 24. creates unique name from hash of content
  • 25. pushes to S3/CDN Managing MediaWhen template rendersContent is hashed => hash value stored in cacheIndividual reference in template replaced{% compress css %}<link href="{{STATIC_URL}}css/admin/base.css" /><link href="{{STATIC_URL}}css/admin/changelists.css" /><link href="{{STATIC_URL}}css/icon_sprites.css"/><link href="{{STATIC_URL}}css/common_10.css" /><link href="{{STATIC_URL}}css/tablesorter.css" /><link href="{{STATIC_URL}}css/multiselect.css" /><link href="{{STATIC_URL}}css/superfish.css" />{% endcompress %}<link rel="stylesheet" href="http://cdn.adstack.com/compress_cache/css/32dd63bd423c.css" />
  • 26. Automatic SpritesWhat are sprites?Sprites are composite images made up of other imagesWhy?Reduce # HTTP requestsHow?CSS is used to only show part of the composite image
  • 27. Automatic SpritesHow do we use sprites?Set them as a css background on a fixed size elementPosition them so only part of the larger image showsCool.But this is really a painCreating imagesCustom css for positioning
  • 29. can help build the sprite automatically
  • 31. Uses python + PIL to generate the sprite
  • 32. Uses pngcrush to optimize the final image size
  • 34. We have a folder full of icons
  • 36. We want to easily put these in templates
  • 37. {% icon "email" %}Automatic SpritesSimple example: lots of icons*doing this can be a pain
  • 38. Automatic Sprites1) Configure Media bundler settingsMEDIA_BUNDLES = (    {"type": "png-sprite",     "name": "icon",     "path": os.path.join(MEDIA_ROOT,"icons"),     "url": "../icons/",     "css_file": os.path.join(MEDIA_ROOT,"css","icon_sprites.css"),     "files": [ “add.png”,“delete.png”,“user.png”,“delete.png”,“group.png”, ]    },)
  • 39. Automatic Sprites1) Configure Media bundler settingsMEDIA_BUNDLES = (    {"type": "png-sprite",     "name": "icon",     "path": os.path.join(MEDIA_ROOT,"icons"),     "url": "../icons/",     "css_file": os.path.join(MEDIA_ROOT,"css","icon_sprites.css"),     "files": filter(lambda x: x[-4:]== '.png',                         os.listdir(os.path.join(MEDIA_ROOT,"icons")))    },)
  • 40. Automatic Sprites2) Bundle our mediapython manage.py bundle_media3) This creates a sprite.png + sprite.css.icon {background-image: url('http://cdn.adstack.com/icons/sprites/icon110701154833.png?675d7dfaa1e1');}.icon_user {width: 16px;background-position: 0px 0px;height: 16px;}.icon_add {width: 16px;background-position: -16px 0px;height: 16px;}Etc…
  • 42. Automatic Sprites5) We can easily write template tags to make this easier#front_end_tags.pyfrom django import templateregister = template.Library()@register.inclusion_tag("common/front_end/icon.html")def icon(icon_name): return locals(){# common/front_end/icon.html #}<span class="icon icon_{{ icon_name }}"></span>6) Now it’s a bit easier to develop<div> {% icon "user" %} Hello Evan</div>
  • 43. AutomationFabric Deploy Script from fabric.api import *defcdn_deploy():run('python manage.py bundle_media')run('python manage.py collectstatic --noinput')run('python manage.py compress')fab cdn_deploy

Editor's Notes

  • #3: How does this relate to Continuous Integration?
  • #4: I’ve worked on a broad range of startups and I’ve w
  • #19: We need this custom storage backend so that it writes both locally and pushes it to S3. I think its local because it will then check to see if it exists on disk and if so it will assume it exists on the CDN
  • #20: You can have your system compress these things on the fly, but I imagine in most cases you actually want it to compress all your media as part of your deploy process