Working on home view
|
@ -3,7 +3,7 @@
|
|||
|
||||
// Focus
|
||||
*:focus {
|
||||
.box-shadow(0, 0, 10px, #47B7F2);
|
||||
.box-shadow(0, 0, 10px, #46CD46);
|
||||
}
|
||||
|
||||
// Mixins
|
||||
|
@ -73,16 +73,29 @@ header {
|
|||
background: #12343D url('/media/images/header-bg.gif') top left repeat-x;
|
||||
border-bottom: 1px solid #DDDDDD;
|
||||
height: 66px;
|
||||
position: relative;
|
||||
z-index: 50;
|
||||
|
||||
div.inner {
|
||||
background: transparent url('/media/images/header-inner-bg.png') top left no-repeat;
|
||||
border-left: 1px solid rgba(229, 229, 229, .25);
|
||||
height: 65px;
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
width: 939px;
|
||||
|
||||
div.shadey {
|
||||
background: transparent url('/media/images/header-inner-bg.png') top left no-repeat;
|
||||
height: 65px;
|
||||
left: -157px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 432px;
|
||||
z-index: 49;
|
||||
}
|
||||
h1 {
|
||||
float: left;
|
||||
position: relative;
|
||||
z-index: 50;
|
||||
|
||||
a {
|
||||
background: transparent url('/media/images/logo.png') top left no-repeat;
|
||||
|
@ -94,13 +107,185 @@ header {
|
|||
width: 87px;
|
||||
}
|
||||
}
|
||||
form.search {
|
||||
float: left;
|
||||
padding: 17px 0 0 20px;
|
||||
position: relative;
|
||||
z-index: 50;
|
||||
|
||||
div.infield {
|
||||
position: relative;
|
||||
|
||||
label {
|
||||
color: #72979C;
|
||||
cursor: text;
|
||||
font: normal 12px @Helvetica;
|
||||
left: 30px;
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
}
|
||||
input {
|
||||
background: #17484F url('/media/images/search-icon.png') top left no-repeat;
|
||||
background: rgba(43, 82, 93, .5) url('/media/images/search-icon.png') 8px center no-repeat;
|
||||
border: 1px solid #3A5E67;
|
||||
color: #FFF;
|
||||
font: normal 12px @Helvetica;
|
||||
margin: 0;
|
||||
padding: 7px;
|
||||
padding-left: 28px;
|
||||
width: 175px;
|
||||
.border-radius(3px);
|
||||
.inset-box-shadow(0, 1px, 0px, #1D4249);
|
||||
}
|
||||
}
|
||||
}
|
||||
nav.public {
|
||||
float: left;
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 17px 0 0 20px;
|
||||
|
||||
li {
|
||||
display: block;
|
||||
float: left;
|
||||
|
||||
a {
|
||||
border-bottom: 2px solid transparent;
|
||||
color: #FFF;
|
||||
display: block;
|
||||
float: left;
|
||||
font: normal 14px @Helvetica;
|
||||
padding: 7px;
|
||||
padding-bottom: 5px;
|
||||
margin-right: 20px;
|
||||
text-decoration: none;
|
||||
-webkit-transition: border .08s linear;
|
||||
-moz-transition: border .08s linear;
|
||||
-o-transition: border .08s linear;
|
||||
transition: border .08s linear;
|
||||
|
||||
&:hover {
|
||||
border-bottom: 2px solid #3A5E67;
|
||||
}
|
||||
&.active {
|
||||
border-bottom: 2px solid #85D2DD;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
aside.nav {
|
||||
border-left: 1px solid rgba(229, 229, 229, .25);
|
||||
float: right;
|
||||
height: 65px;
|
||||
width: 189px;
|
||||
}
|
||||
}
|
||||
}
|
||||
section.main {
|
||||
border-left: 1px solid #DDDDDD;
|
||||
height: 100%;
|
||||
margin: 0 auto;
|
||||
width: 939px;
|
||||
padding-top: 30px;
|
||||
position: relative;
|
||||
width: 940px;
|
||||
|
||||
div.ruler {
|
||||
background: #DDDDDD;
|
||||
height: 100%;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
width: 1px;
|
||||
z-index: 48;
|
||||
}
|
||||
div.right-y {
|
||||
margin-left: 750px;
|
||||
}
|
||||
div.inner {
|
||||
float: left;
|
||||
width: 750px;
|
||||
}
|
||||
aside.main {
|
||||
float: right;
|
||||
width: 190px;
|
||||
|
||||
section.ad {
|
||||
div.asset {
|
||||
background: #FFF url('/media/images/ad.jpg') center center no-repeat;
|
||||
border: 1px solid #DDDDDD;
|
||||
height: 130px;
|
||||
margin: 15px 15px 6px;
|
||||
width: 158px;
|
||||
.border-radius(3px);
|
||||
}
|
||||
div.meta {
|
||||
color: #CCC;
|
||||
font: normal 12px @Helvetica;
|
||||
margin-right: 15px;
|
||||
text-align: right;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
}
|
||||
section.tags {
|
||||
margin: 45px 15px;
|
||||
|
||||
h1 {
|
||||
background: transparent url('/media/images/tags-icon.png') 0 0 no-repeat;
|
||||
color: #3BAAF3;
|
||||
font: bold 12px @Helvetica;
|
||||
padding-bottom: 5px;
|
||||
padding-left: 22px;
|
||||
}
|
||||
ul {
|
||||
margin: 0 0 15px 0;
|
||||
|
||||
li {
|
||||
margin: 6px 0 6px 22px;
|
||||
}
|
||||
}
|
||||
a {
|
||||
border-bottom: 1px solid #5AB6F4;
|
||||
color: #5AB6F4;
|
||||
font: normal 12px @Helvetica;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
border-bottom: 1px solid #2B6E9B;
|
||||
color: #2B6E9B;
|
||||
}
|
||||
&.view-all {
|
||||
font-weight: bold;
|
||||
margin: 0 0 0 22px;
|
||||
}
|
||||
}
|
||||
}
|
||||
nav.footer {
|
||||
margin: 45px 15px 32px;
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
|
||||
li {
|
||||
background: transparent url('/media/images/api-icon.png') center left no-repeat;
|
||||
margin: 6px 0 6px 0;
|
||||
padding-left: 22px;
|
||||
|
||||
a {
|
||||
border-bottom: 1px solid #C5C5C6;
|
||||
color: #999;
|
||||
font: bold 12px @Helvetica;
|
||||
text-decoration: none;
|
||||
}
|
||||
&.twitter {
|
||||
background: transparent url('/media/images/twitter-icon.png') 4px center no-repeat;
|
||||
}
|
||||
&.pro {
|
||||
background: transparent url('/media/images/upgrade-icon.png') 2px center no-repeat;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Utils
|
||||
|
|
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 1.1 KiB |
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* jQuery Hotkeys Plugin
|
||||
* Copyright 2010, John Resig
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
*
|
||||
* Based upon the plugin by Tzury Bar Yochay:
|
||||
* http://github.com/tzuryby/hotkeys
|
||||
*
|
||||
* Original idea by:
|
||||
* Binny V A, http://www.openjs.com/scripts/events/keyboard_shortcuts/
|
||||
*/
|
||||
|
||||
(function(jQuery){
|
||||
|
||||
jQuery.hotkeys = {
|
||||
version: "0.8",
|
||||
|
||||
specialKeys: {
|
||||
8: "backspace", 9: "tab", 13: "return", 16: "shift", 17: "ctrl", 18: "alt", 19: "pause",
|
||||
20: "capslock", 27: "esc", 32: "space", 33: "pageup", 34: "pagedown", 35: "end", 36: "home",
|
||||
37: "left", 38: "up", 39: "right", 40: "down", 45: "insert", 46: "del",
|
||||
96: "0", 97: "1", 98: "2", 99: "3", 100: "4", 101: "5", 102: "6", 103: "7",
|
||||
104: "8", 105: "9", 106: "*", 107: "+", 109: "-", 110: ".", 111 : "/",
|
||||
112: "f1", 113: "f2", 114: "f3", 115: "f4", 116: "f5", 117: "f6", 118: "f7", 119: "f8",
|
||||
120: "f9", 121: "f10", 122: "f11", 123: "f12", 144: "numlock", 145: "scroll", 191: "/", 224: "meta"
|
||||
},
|
||||
|
||||
shiftNums: {
|
||||
"`": "~", "1": "!", "2": "@", "3": "#", "4": "$", "5": "%", "6": "^", "7": "&",
|
||||
"8": "*", "9": "(", "0": ")", "-": "_", "=": "+", ";": ": ", "'": "\"", ",": "<",
|
||||
".": ">", "/": "?", "\\": "|"
|
||||
}
|
||||
};
|
||||
|
||||
function keyHandler( handleObj ) {
|
||||
// Only care when a possible input has been specified
|
||||
if ( typeof handleObj.data !== "string" ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var origHandler = handleObj.handler,
|
||||
keys = handleObj.data.toLowerCase().split(" ");
|
||||
|
||||
handleObj.handler = function( event ) {
|
||||
// Don't fire in text-accepting inputs that we didn't directly bind to
|
||||
if ( this !== event.target && (/textarea|select/i.test( event.target.nodeName ) ||
|
||||
event.target.type === "text") ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Keypress represents characters, not special keys
|
||||
var special = event.type !== "keypress" && jQuery.hotkeys.specialKeys[ event.which ],
|
||||
character = String.fromCharCode( event.which ).toLowerCase(),
|
||||
key, modif = "", possible = {};
|
||||
|
||||
// check combinations (alt|ctrl|shift+anything)
|
||||
if ( event.altKey && special !== "alt" ) {
|
||||
modif += "alt+";
|
||||
}
|
||||
|
||||
if ( event.ctrlKey && special !== "ctrl" ) {
|
||||
modif += "ctrl+";
|
||||
}
|
||||
|
||||
// TODO: Need to make sure this works consistently across platforms
|
||||
if ( event.metaKey && !event.ctrlKey && special !== "meta" ) {
|
||||
modif += "meta+";
|
||||
}
|
||||
|
||||
if ( event.shiftKey && special !== "shift" ) {
|
||||
modif += "shift+";
|
||||
}
|
||||
|
||||
if ( special ) {
|
||||
possible[ modif + special ] = true;
|
||||
|
||||
} else {
|
||||
possible[ modif + character ] = true;
|
||||
possible[ modif + jQuery.hotkeys.shiftNums[ character ] ] = true;
|
||||
|
||||
// "$" can be triggered as "Shift+4" or "Shift+$" or just "$"
|
||||
if ( modif === "shift+" ) {
|
||||
possible[ jQuery.hotkeys.shiftNums[ character ] ] = true;
|
||||
}
|
||||
}
|
||||
|
||||
for ( var i = 0, l = keys.length; i < l; i++ ) {
|
||||
if ( possible[ keys[i] ] ) {
|
||||
return origHandler.apply( this, arguments );
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
jQuery.each([ "keydown", "keyup", "keypress" ], function() {
|
||||
jQuery.event.special[ this ] = { add: keyHandler };
|
||||
});
|
||||
|
||||
})( jQuery );
|
|
@ -0,0 +1,154 @@
|
|||
/**
|
||||
* @license In-Field Label jQuery Plugin
|
||||
* http://fuelyourcoding.com/scripts/infield.html
|
||||
*
|
||||
* Copyright (c) 2009-2010 Doug Neiner
|
||||
* Dual licensed under the MIT and GPL licenses.
|
||||
* Uses the same license as jQuery, see:
|
||||
* http://docs.jquery.com/License
|
||||
*
|
||||
* @version 0.1.2
|
||||
*/
|
||||
(function ($) {
|
||||
|
||||
$.InFieldLabels = function (label, field, options) {
|
||||
// To avoid scope issues, use 'base' instead of 'this'
|
||||
// to reference this class from internal events and functions.
|
||||
var base = this;
|
||||
|
||||
// Access to jQuery and DOM versions of each element
|
||||
base.$label = $(label);
|
||||
base.label = label;
|
||||
|
||||
base.$field = $(field);
|
||||
base.field = field;
|
||||
|
||||
base.$label.data("InFieldLabels", base);
|
||||
base.showing = true;
|
||||
|
||||
base.init = function () {
|
||||
// Merge supplied options with default options
|
||||
base.options = $.extend({}, $.InFieldLabels.defaultOptions, options);
|
||||
|
||||
// Check if the field is already filled in
|
||||
if (base.$field.val() !== "") {
|
||||
base.$label.hide();
|
||||
base.showing = false;
|
||||
}
|
||||
|
||||
base.$field.focus(function () {
|
||||
base.fadeOnFocus();
|
||||
}).blur(function () {
|
||||
base.checkForEmpty(true);
|
||||
}).bind('keydown.infieldlabel', function (e) {
|
||||
// Use of a namespace (.infieldlabel) allows us to
|
||||
// unbind just this method later
|
||||
base.hideOnChange(e);
|
||||
}).bind('paste', function (e) {
|
||||
// Since you can not paste an empty string we can assume
|
||||
// that the fieldis not empty and the label can be cleared.
|
||||
base.setOpacity(0.0);
|
||||
}).change(function (e) {
|
||||
base.checkForEmpty();
|
||||
}).bind('onPropertyChange', function () {
|
||||
base.checkForEmpty();
|
||||
});
|
||||
};
|
||||
|
||||
// If the label is currently showing
|
||||
// then fade it down to the amount
|
||||
// specified in the settings
|
||||
base.fadeOnFocus = function () {
|
||||
if (base.showing) {
|
||||
base.setOpacity(base.options.fadeOpacity);
|
||||
}
|
||||
};
|
||||
|
||||
base.setOpacity = function (opacity) {
|
||||
base.$label.stop().animate({ opacity: opacity }, base.options.fadeDuration);
|
||||
base.showing = (opacity > 0.0);
|
||||
};
|
||||
|
||||
// Checks for empty as a fail safe
|
||||
// set blur to true when passing from
|
||||
// the blur event
|
||||
base.checkForEmpty = function (blur) {
|
||||
if (base.$field.val() === "") {
|
||||
base.prepForShow();
|
||||
base.setOpacity(blur ? 1.0 : base.options.fadeOpacity);
|
||||
} else {
|
||||
base.setOpacity(0.0);
|
||||
}
|
||||
};
|
||||
|
||||
base.prepForShow = function (e) {
|
||||
if (!base.showing) {
|
||||
// Prepare for a animate in...
|
||||
base.$label.css({opacity: 0.0}).show();
|
||||
|
||||
// Reattach the keydown event
|
||||
base.$field.bind('keydown.infieldlabel', function (e) {
|
||||
base.hideOnChange(e);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
base.hideOnChange = function (e) {
|
||||
if (
|
||||
(e.keyCode === 16) || // Skip Shift
|
||||
(e.keyCode === 9) // Skip Tab
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (base.showing) {
|
||||
base.$label.hide();
|
||||
base.showing = false;
|
||||
}
|
||||
|
||||
// Remove keydown event to save on CPU processing
|
||||
base.$field.unbind('keydown.infieldlabel');
|
||||
};
|
||||
|
||||
// Run the initialization method
|
||||
base.init();
|
||||
};
|
||||
|
||||
$.InFieldLabels.defaultOptions = {
|
||||
fadeOpacity: 0.5, // Once a field has focus, how transparent should the label be
|
||||
fadeDuration: 300 // How long should it take to animate from 1.0 opacity to the fadeOpacity
|
||||
};
|
||||
|
||||
|
||||
$.fn.inFieldLabels = function (options) {
|
||||
return this.each(function () {
|
||||
// Find input or textarea based on for= attribute
|
||||
// The for attribute on the label must contain the ID
|
||||
// of the input or textarea element
|
||||
var for_attr = $(this).attr('for'), $field;
|
||||
if (!for_attr) {
|
||||
return; // Nothing to attach, since the for field wasn't used
|
||||
}
|
||||
|
||||
// Find the referenced input or textarea element
|
||||
$field = $(
|
||||
"input#" + for_attr + "[type='text']," +
|
||||
"input#" + for_attr + "[type='search']," +
|
||||
"input#" + for_attr + "[type='tel']," +
|
||||
"input#" + for_attr + "[type='url']," +
|
||||
"input#" + for_attr + "[type='email']," +
|
||||
"input#" + for_attr + "[type='password']," +
|
||||
"textarea#" + for_attr
|
||||
);
|
||||
|
||||
if ($field.length === 0) {
|
||||
return; // Again, nothing to attach
|
||||
}
|
||||
|
||||
// Only create object for input[text], input[password], or textarea
|
||||
(new $.InFieldLabels(this, $field[0], options));
|
||||
});
|
||||
};
|
||||
|
||||
}(jQuery));
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
$ =>
|
||||
$(document).bind('keyup', '/', -> $('input#search-query').focus() )
|
||||
|
||||
$('div.infield label').inFieldLabels()
|
||||
|
||||
false
|
|
@ -1 +0,0 @@
|
|||
$(function() {});
|
|
@ -33,7 +33,7 @@ class PublicTagResource(ModelResource):
|
|||
|
||||
def dehydrate(self, bundle):
|
||||
bundle.data['absolute_url'] = '/public/tag/%s/' % bundle.obj.slug
|
||||
bundle.data['snipts'] = '/api/public/snipt/?tag=%d' % bundle.obj.id
|
||||
#bundle.data['snipts'] = '/api/public/snipt/?tag=%d' % bundle.obj.id
|
||||
bundle.data['count'] = bundle.obj.taggit_taggeditem_items.filter(
|
||||
snipt__public=True).count()
|
||||
return bundle
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
from django.conf.urls.defaults import *
|
||||
|
||||
from snipts import views
|
||||
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^$', views.home, name='home'),
|
||||
)
|
|
@ -1 +1,13 @@
|
|||
# Create your views here.
|
||||
from annoying.decorators import render_to
|
||||
from snipts.api import PublicTagResource
|
||||
|
||||
@render_to('home.html')
|
||||
def home(request):
|
||||
tr = PublicTagResource()
|
||||
tags_queryset = tr.cached_obj_get_list()[:20]
|
||||
tags_bundles = (tr.build_bundle(request=request, obj=tag) for tag in tags_queryset)
|
||||
tags = [tr.full_dehydrate(bundle) for bundle in tags_bundles]
|
||||
|
||||
return {
|
||||
'tags': tags
|
||||
}
|
||||
|
|
|
@ -19,7 +19,10 @@
|
|||
|
||||
{% compress js %}
|
||||
<script type="text/javascript" src="/media/js/jquery.js"></script>
|
||||
<script type="text/javascript" src="/media/js/script.js"></script>
|
||||
<script type="text/javascript" src="/media/js/jquery.infieldlabel.js"></script>
|
||||
<script type="text/javascript" src="/media/js/jquery.hotkeys.js"></script>
|
||||
<script type="text/javascript" src="/media/js/coffee-script.js"></script>
|
||||
<script type="text/coffeescript" src="/media/js/script.coffee"></script>
|
||||
{% if debug %}
|
||||
<script type="text/javascript" src="/media/js/less.js"></script>
|
||||
{% endif %}
|
||||
|
@ -43,12 +46,73 @@
|
|||
|
||||
<header>
|
||||
<div class="inner">
|
||||
<div class="shadey"></div>
|
||||
<h1><a href="/">Snipt</a></h1>
|
||||
<form class="search" action="/public/search/" method="get">
|
||||
<fieldset>
|
||||
<div class="fields infield">
|
||||
<label for="search-query">Search public snipts</label>
|
||||
<input type="text" id="search-query" name="q" value="" />
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
<nav class="public">
|
||||
<ul>
|
||||
<li>
|
||||
<a href="/" class="active">Public snipts</a>
|
||||
</li>
|
||||
{% if not request.user.is_authenticated %}
|
||||
<li>
|
||||
<a href="/login/">Log in</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/signup/">Sign up</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</nav>
|
||||
<aside class="nav"></aside>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<section class="main">
|
||||
{% block content %}{% endblock %}
|
||||
<section class="main group">
|
||||
<div class="inner">
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
<div class="left-y ruler"></div>
|
||||
<div class="right-y ruler"></div>
|
||||
<aside class="main">
|
||||
<section class="ad">
|
||||
<div class="asset"></div>
|
||||
<div class="meta">
|
||||
Ads by Carbon
|
||||
</div>
|
||||
</section>
|
||||
<section class="tags">
|
||||
<h1>Popular public tags</h1>
|
||||
<ul>
|
||||
{% for tag in tags %}
|
||||
<li>
|
||||
<a href="{{ tag.data.absolute_url }}">{{ tag.data.name }} ({{ tag.data.count }})</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<a href="/public/tags/" class="view-all">View all »</a>
|
||||
</section>
|
||||
<nav class="footer">
|
||||
<ul>
|
||||
<li class="api">
|
||||
<a href="/api/">API</a>
|
||||
</li>
|
||||
<li class="twitter">
|
||||
<a href="https://twitter.com/#!/snipt">@snipt</a>
|
||||
</li>
|
||||
<li class="pro">
|
||||
<a href="/pro/">Go Pro</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</aside>
|
||||
</section>
|
||||
|
||||
{% if not debug %}
|
||||
|
|
3
urls.py
|
@ -3,7 +3,6 @@ from django.views.generic.simple import direct_to_template
|
|||
from django.conf.urls.defaults import *
|
||||
from django.contrib import admin
|
||||
from tastypie.api import Api
|
||||
from views import home
|
||||
|
||||
admin.autodiscover()
|
||||
|
||||
|
@ -22,5 +21,5 @@ urlpatterns = patterns('',
|
|||
|
||||
url(r'^api/', include(public_api.urls)),
|
||||
|
||||
url(r'^$', home),
|
||||
url(r'^', include('snipts.urls')),
|
||||
)
|
||||
|
|