diff options
| author | Sean Brant | 2013-03-10 18:39:11 -0500 |
|---|---|---|
| committer | Sean Brant | 2013-03-10 18:39:17 -0500 |
| commit | a335c4fe1544eceaa33e77a88b32edb1dea2108a (patch) | |
| tree | eaa356757922367a1a9b13c7c6c985a45a43ed9b | |
| parent | 9d729155580ea5212386c0f7d71f4b89809073e5 (diff) | |
| download | pykss-a335c4fe1544eceaa33e77a88b32edb1dea2108a.tar.bz2 | |
Adds pykss.contrib.django
Provides a generic view as well as a template tag for generating
style guides.
20 files changed, 472 insertions, 0 deletions
@@ -50,3 +50,10 @@ Usage >>> >>> styleguide.section('2.1.1').modifiers[0].description 'Subtle hover highlight' + + +Django Usage +------------ +If you would like to use KSS within a Django project `pykss.contrib.django` +provides a view and template tag to make it easier. Check out the example +Django project for usage. diff --git a/examples/djangoproject/djangoproject/__init__.py b/examples/djangoproject/djangoproject/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/examples/djangoproject/djangoproject/__init__.py diff --git a/examples/djangoproject/djangoproject/settings.py b/examples/djangoproject/djangoproject/settings.py new file mode 100644 index 0000000..39b1c62 --- /dev/null +++ b/examples/djangoproject/djangoproject/settings.py @@ -0,0 +1,25 @@ +import os + +PROJECT_ROOT = os.path.dirname(__file__) + +DEBUG = True +SECRET_KEY = 'G0GS4C7QLq3FhdDYrNtDuEBoLuXzDqaS' +ROOT_URLCONF = 'djangoproject.urls' + +TEMPLATE_DIRS = [os.path.join(PROJECT_ROOT, 'templates')] + +STATIC_URL = '/static/' +STATIC_ROOT = os.path.join(PROJECT_ROOT, 'public') + +STATICFILES_DIRS = [os.path.join(PROJECT_ROOT, 'static')] +STATICFILES_FINDERS = [ + 'django.contrib.staticfiles.finders.FileSystemFinder', + 'django.contrib.staticfiles.finders.AppDirectoriesFinder', +] + +PYKSS_DIRS = [os.path.join(PROJECT_ROOT, 'static', 'css')] + +INSTALLED_APPS = [ + 'django.contrib.staticfiles', + 'pykss.contrib.django', +] diff --git a/examples/djangoproject/djangoproject/static/css/buttons.css b/examples/djangoproject/djangoproject/static/css/buttons.css new file mode 100644 index 0000000..edcb4b3 --- /dev/null +++ b/examples/djangoproject/djangoproject/static/css/buttons.css @@ -0,0 +1,50 @@ +/* +Your standard form button. + +:hover - Highlights when hovering. +:disabled - Dims the button when disabled. +.primary - Indicates button is the primary action. +.smaller - A smaller button + +Styleguide 1.1 +*/ +button { + padding: 5px 15px; + line-height: normal; + font-family: "Helvetica Neue", Helvetica; + font-size: 12px; + font-weight: bold; + color: #666; + text-shadow: 0 1px rgba(255, 255, 255, 0.9); + border-radius: 3px; + border: 1px solid #ddd; + border-bottom-color: #bbb; + background: #f5f5f5; + filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='$start', endColorstr='$end'); + background: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e5e5e5)); + background: -moz-linear-gradient(top, #f5f5f5, #e5e5e5); + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15); + cursor: pointer; } + button.primary, button.primary:hover { + color: #fff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.4); + border-color: #74bb5a; + border-bottom-color: #509338; + background: #8add6d; + filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='$start', endColorstr='$end'); + background: -webkit-gradient(linear, left top, left bottom, from(#8add6d), to(#60b044)); + background: -moz-linear-gradient(top, #8add6d, #60b044); + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2); } + button.smaller { + font-size: 11px; + padding: 4px 7px; } + button:hover { + color: #337797; + background: #f0f7fa; + filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='$start', endColorstr='$end'); + background: -webkit-gradient(linear, left top, left bottom, from(#f0f7fa), to(#d8eaf2)); + background: -moz-linear-gradient(top, #f0f7fa, #d8eaf2); + border-color: #cbe3ee; + border-bottom-color: #97c7dd; } + button:disabled { + opacity: 0.5; } diff --git a/examples/djangoproject/djangoproject/static/css/layout.css b/examples/djangoproject/djangoproject/static/css/layout.css new file mode 100644 index 0000000..871d414 --- /dev/null +++ b/examples/djangoproject/djangoproject/static/css/layout.css @@ -0,0 +1,143 @@ +/*---------------------------------------------------------------------------- + @group Global Reset +----------------------------------------------------------------------------*/ +* { + padding:0; + margin:0; +} +h1, h2, h3, h4, h5, h6, p, pre, blockquote, label, ul, ol, dl, fieldset, address { margin:1em 0; } +li, dd { margin-left:5%; } +fieldset { padding: .5em; } +select option{ padding:0 5px; } + +.access{ display:none; } /* For accessibility related elements */ +.clear{ clear:both; height:0px; font-size:0px; line-height:0px; overflow:hidden; } +a{ outline:none; } +a img{ border:none; } + +.clearfix:after { + content: "."; + display: block; + height: 0; + clear: both; + visibility: hidden; +} +* html .clearfix {height: 1%;} +.clearfix {display:inline-block;} +.clearfix {display: block;} + +/* @end */ + +body{ + font-family:Helvetica, Arial, sans-serif; + font-size:14px; +} + +header{ + padding:10px; + + font-size:16px; + color:#666; + + background:#f1f1f1; + border-bottom:1px solid #ddd; +} + +#wrapper{ + width:600px; + padding-left:200px; +} + +nav[role=main]{ + float:left; + margin-left:-200px; + width:160px; +} +nav ul{ + margin-left:10px; +} +nav li{ + list-style-type:none; + margin:10px 0; +} +nav li a{ + text-decoration:none; + color:#666; +} + +/*---------------------------------------------------------------------------- + @group Styleguide Styles +----------------------------------------------------------------------------*/ + +h1.styleguide { + margin: 0 0 -5px 0; + font-size: 24px; + color: #000; } + +.styleguide-example { + margin: 15px 0; + background: rgba(255, 255, 255, 0.5); + border: 1px solid #ddd; + box-shadow: 0 0 5px rgba(0, 0, 0, 0.1); } + .styleguide-example > h3 { + margin: 0; + padding: 5px; + color: #fff; + font-size: 12px; + text-transform: uppercase; + background: #333; + border-top: 1px solid #000; } + .styleguide-example > h3 em { + float: right; + text-transform: none; + font-style: normal; + font-weight: normal; + color: #999; } + .styleguide-example .styleguide-description { + padding: 10px 5px; + background: #f1f1f1; + border-bottom: 1px solid #ddd; } + .styleguide-example .styleguide-description p:first-child { + margin-top: 0; } + .styleguide-example .styleguide-description p:last-child { + margin-bottom: 0; } + .styleguide-example .styleguide-element { + position: relative; + padding: 20px; } + .styleguide-example .styleguide-element + .styleguide-element { + margin-top: -5px; + padding-top: 15px; + border-top: 1px solid #eee; } + .styleguide-example .styleguide-element .styleguide-modifier-name { + display: block; + position: absolute; + top: 0; + right: 0; + padding: 5px 8px; + font-size: 11px; + color: #999; + background: #f9f9f9; + border: 1px solid #eee; + border-top: none; } + .styleguide-example .styleguide-html { + padding: 5px 10px; + background: #edf6f8; + border-top: 1px solid #dde7ea; + overflow: auto; } + .styleguide-example .styleguide-html .highlight { + background: none; } + .styleguide-example ul.styleguide-modifiers { + margin: 0 0 0 10px; } + .styleguide-example ul.styleguide-modifiers li { + list-style-type: none; + margin-left: 0; } + .styleguide-example ul.styleguide-modifiers li strong { + font-family: Monaco, monospace; + font-size: 12px; + font-weight: normal; + color: #222; } + .styleguide-example > .styleguide-code { + font-family: Monaco, monospace; + } + +/* @end */ diff --git a/examples/djangoproject/djangoproject/templates/base.html b/examples/djangoproject/djangoproject/templates/base.html new file mode 100644 index 0000000..f52ed82 --- /dev/null +++ b/examples/djangoproject/djangoproject/templates/base.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +{% load static %} +<html> + <head> + <meta http-equiv="content-type" content="text/html;charset=UTF-8" /> + <title>Styleguide Example</title> + <link rel="stylesheet" href="{% static "css/layout.css" %}" type="text/css" /> + <link rel="stylesheet" href="{% static "css/buttons.css" %}" type="text/css" /> + </head> + <body> + <header>Styleguide Example</header> + <div id="wrapper"> + <nav role="main"> + <ul> + <li><a href="{% url "index" %}">Home</a></li> + <li><a href="{% url "styleguide" %}">Styleguide</a></li> + </ul> + </nav> + {% block content %}{% endblock %} + </div> + <script src="{% static "pykss/js/kss.js" %}"></script> + </body> +</html> diff --git a/examples/djangoproject/djangoproject/templates/index.html b/examples/djangoproject/djangoproject/templates/index.html new file mode 100644 index 0000000..06660ce --- /dev/null +++ b/examples/djangoproject/djangoproject/templates/index.html @@ -0,0 +1,8 @@ +{% extends "base.html" %} + +{% block content %} +<h1>Welcome</h1> +<p>This is an example site. It doesn't really do anything, but it does have some rad buttons</p> +<p><button>I am a button</button></p> +<p>Check out the <a href="{% url "styleguide" %}">styleguide</a> to see the value here.</p> +{% endblock %} diff --git a/examples/djangoproject/djangoproject/templates/styleguide.html b/examples/djangoproject/djangoproject/templates/styleguide.html new file mode 100644 index 0000000..05d736d --- /dev/null +++ b/examples/djangoproject/djangoproject/templates/styleguide.html @@ -0,0 +1,19 @@ +{% extends "base.html" %} +{% load pykss %} + +{% block content %} +{% styleguideblock styleguide "1.1" %} + <button class="{{ modifier.class_name }}">Example Button</button> +{% endstyleguideblock %} + +{% verbatim %} +<p>This block above was created with a simple template call:</p> +<pre> + <code> +{% styleguideblock styleguide "1.1" %} + <button class="{{ modifier.class_name }}">Example Button</button> +{% endstyleguideblock %} + </code> +</pre> +{% endverbatim %} +{% endblock %} diff --git a/examples/djangoproject/djangoproject/urls.py b/examples/djangoproject/djangoproject/urls.py new file mode 100644 index 0000000..061ec2c --- /dev/null +++ b/examples/djangoproject/djangoproject/urls.py @@ -0,0 +1,10 @@ +from django.conf.urls import patterns, url +from django.views.generic.base import TemplateView + +from pykss.contrib.django.views import StyleGuideView + + +urlpatterns = patterns('', + url(r'^$', TemplateView.as_view(template_name='index.html'), name='index'), + url(r'^styleguide/$', StyleGuideView.as_view(template_name='styleguide.html'), name='styleguide'), +) diff --git a/examples/djangoproject/djangoproject/wsgi.py b/examples/djangoproject/djangoproject/wsgi.py new file mode 100644 index 0000000..d306fe1 --- /dev/null +++ b/examples/djangoproject/djangoproject/wsgi.py @@ -0,0 +1,5 @@ +import os +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoproject.settings') + +from django.core.wsgi import get_wsgi_application +application = get_wsgi_application() diff --git a/examples/djangoproject/manage.py b/examples/djangoproject/manage.py new file mode 100644 index 0000000..6c0acfc --- /dev/null +++ b/examples/djangoproject/manage.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python +import os +import sys + + +if __name__ == '__main__': + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoproject.settings') + + from django.core.management import execute_from_command_line + execute_from_command_line(sys.argv) diff --git a/examples/djangoproject/requirements.txt b/examples/djangoproject/requirements.txt new file mode 100644 index 0000000..c52f862 --- /dev/null +++ b/examples/djangoproject/requirements.txt @@ -0,0 +1,2 @@ +Django==1.5 +https://github.com/seanbrant/pykss.git diff --git a/pykss/contrib/__init__.py b/pykss/contrib/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/pykss/contrib/__init__.py diff --git a/pykss/contrib/django/__init__.py b/pykss/contrib/django/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/pykss/contrib/django/__init__.py diff --git a/pykss/contrib/django/models.py b/pykss/contrib/django/models.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/pykss/contrib/django/models.py diff --git a/pykss/contrib/django/static/pykss/js/kss.js b/pykss/contrib/django/static/pykss/js/kss.js new file mode 100644 index 0000000..14a95cc --- /dev/null +++ b/pykss/contrib/django/static/pykss/js/kss.js @@ -0,0 +1,47 @@ +(function() { + var KssStateGenerator; + + KssStateGenerator = (function() { + + function KssStateGenerator() { + var idx, idxs, pseudos, replaceRule, rule, stylesheet, _i, _len, _len2, _ref, _ref2; + pseudos = /(\:hover|\:disabled|\:active|\:visited|\:focus)/g; + try { + _ref = document.styleSheets; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + stylesheet = _ref[_i]; + idxs = []; + _ref2 = stylesheet.cssRules; + for (idx = 0, _len2 = _ref2.length; idx < _len2; idx++) { + rule = _ref2[idx]; + if ((rule.type === CSSRule.STYLE_RULE) && pseudos.test(rule.selectorText)) { + replaceRule = function(matched, stuff) { + return matched.replace(/\:/g, '.pseudo-class-'); + }; + this.insertRule(rule.cssText.replace(pseudos, replaceRule)); + } + } + } + } catch (_error) {} + } + + KssStateGenerator.prototype.insertRule = function(rule) { + var headEl, styleEl; + headEl = document.getElementsByTagName('head')[0]; + styleEl = document.createElement('style'); + styleEl.type = 'text/css'; + if (styleEl.styleSheet) { + styleEl.styleSheet.cssText = rule; + } else { + styleEl.appendChild(document.createTextNode(rule)); + } + return headEl.appendChild(styleEl); + }; + + return KssStateGenerator; + + })(); + + new KssStateGenerator; + +}).call(this); diff --git a/pykss/contrib/django/templates/pykss/styleguideblock.html b/pykss/contrib/django/templates/pykss/styleguideblock.html new file mode 100644 index 0000000..8521ee1 --- /dev/null +++ b/pykss/contrib/django/templates/pykss/styleguideblock.html @@ -0,0 +1,37 @@ +<div class="styleguide-example"> + {% block styleguide_header %} + <h3>{{ section.section }} <em>{{ section.filename }}</em></h3> + {% endblock %} + + {% block styleguide_description %} + <div class="styleguide-description"> + <p>{{ section.description }}</p> + {% if section.modifiers %} + <ul class="styleguide-modifier"> + {% for modifier in section.modifiers %} + <li><strong>{{ modifier.name }}</strong> - {{ modifier.description }}</li> + {% endfor %} + </ul> + {% endif %} + </div> + {% endblock %} + + {% block styleguide_element %} + <div class="styleguide-element"> + {{ example_html }} + </div> + {% endblock %} + + {% block styleguide_modifier_elements %} + {% for example in modifier_examples %} + <div class="styleguide-element styleguide-modifier"> + <span class="styleguide-modifier-name">{{ example.modifier.name }}</span> + {{ example.html }} + </div> + {% endfor %} + {% endblock %} + + {% block styleguide_code %} + <pre class="styleguide-code">{{ escaped_html }}</pre> + {% endblock %} +</div> diff --git a/pykss/contrib/django/templatetags/__init__.py b/pykss/contrib/django/templatetags/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/pykss/contrib/django/templatetags/__init__.py diff --git a/pykss/contrib/django/templatetags/pykss.py b/pykss/contrib/django/templatetags/pykss.py new file mode 100644 index 0000000..f833ade --- /dev/null +++ b/pykss/contrib/django/templatetags/pykss.py @@ -0,0 +1,66 @@ +from django import template +from django.template.loader import render_to_string + + +register = template.Library() + + +class StyleGuideBlockNode(template.Node): + + def __init__(self, styleguide, reference, template_name, nodelist): + self.styleguide = styleguide + self.reference = reference + self.template_name = template_name + self.nodelist = nodelist + + def __repr__(self): + return '<StyleGuideBlockNode>' + + def render(self, context): + styleguide = self.styleguide.resolve(context) + reference = self.reference.resolve(context) + template_name = self.template_name.resolve(context) + + section = styleguide.section(reference) + + example_html = self.nodelist.render(context) + + modifier_examples = [] + for modifier in section.modifiers: + context.update({'modifier': modifier}) + modifier_examples.append({ + 'modifier': modifier, + 'html': self.nodelist.render(context), + }) + + output = render_to_string(template_name, { + 'section': section, + 'example_html': example_html, + 'modifier_examples': modifier_examples, + }) + + return output + + +@register.tag +def styleguideblock(parser, token): + bits = token.contents.split() + + if len(bits) != 3: + raise template.TemplateSyntaxError("styleguideblock expected at least two arguments") + + try: + tag, styleguide, reference, template_name = bits + except ValueError: + tag, styleguide, reference = bits + template_name = '"pykss/styleguideblock.html"' + + nodelist = parser.parse(('endstyleguideblock',)) + parser.delete_first_token() + + return StyleGuideBlockNode( + styleguide=parser.compile_filter(styleguide), + reference=parser.compile_filter(reference), + template_name=parser.compile_filter(template_name), + nodelist=nodelist, + ) diff --git a/pykss/contrib/django/views.py b/pykss/contrib/django/views.py new file mode 100644 index 0000000..853bfc2 --- /dev/null +++ b/pykss/contrib/django/views.py @@ -0,0 +1,20 @@ +from django.conf import settings +from django.views.generic.base import TemplateView + +import pykss + + +class StyleGuideMixin(object): + + def get_styleguid(self): + dirs = getattr(settings, 'PYKSS_DIRS', []) + return pykss.Parser(*dirs) + + def get_context_data(self, **kwargs): + context = {'styleguide': self.get_styleguid()} + context.update(kwargs) + return super(StyleGuideMixin, self).get_context_data(**context) + + +class StyleGuideView(StyleGuideMixin, TemplateView): + pass |
