aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Brant2013-03-10 18:39:11 -0500
committerSean Brant2013-03-10 18:39:17 -0500
commita335c4fe1544eceaa33e77a88b32edb1dea2108a (patch)
treeeaa356757922367a1a9b13c7c6c985a45a43ed9b
parent9d729155580ea5212386c0f7d71f4b89809073e5 (diff)
downloadpykss-a335c4fe1544eceaa33e77a88b32edb1dea2108a.tar.bz2
Adds pykss.contrib.django
Provides a generic view as well as a template tag for generating style guides.
-rw-r--r--README.rst7
-rw-r--r--examples/djangoproject/djangoproject/__init__.py0
-rw-r--r--examples/djangoproject/djangoproject/settings.py25
-rw-r--r--examples/djangoproject/djangoproject/static/css/buttons.css50
-rw-r--r--examples/djangoproject/djangoproject/static/css/layout.css143
-rw-r--r--examples/djangoproject/djangoproject/templates/base.html23
-rw-r--r--examples/djangoproject/djangoproject/templates/index.html8
-rw-r--r--examples/djangoproject/djangoproject/templates/styleguide.html19
-rw-r--r--examples/djangoproject/djangoproject/urls.py10
-rw-r--r--examples/djangoproject/djangoproject/wsgi.py5
-rw-r--r--examples/djangoproject/manage.py10
-rw-r--r--examples/djangoproject/requirements.txt2
-rw-r--r--pykss/contrib/__init__.py0
-rw-r--r--pykss/contrib/django/__init__.py0
-rw-r--r--pykss/contrib/django/models.py0
-rw-r--r--pykss/contrib/django/static/pykss/js/kss.js47
-rw-r--r--pykss/contrib/django/templates/pykss/styleguideblock.html37
-rw-r--r--pykss/contrib/django/templatetags/__init__.py0
-rw-r--r--pykss/contrib/django/templatetags/pykss.py66
-rw-r--r--pykss/contrib/django/views.py20
20 files changed, 472 insertions, 0 deletions
diff --git a/README.rst b/README.rst
index 232f2ab..0738c12 100644
--- a/README.rst
+++ b/README.rst
@@ -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" %}
+ &lt;button class="{{ modifier.class_name }}"&gt;Example Button&lt;/button&gt;
+{% 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