Browse Source

Basic image promotions now working

master
David Winterbottom 14 years ago
parent
commit
6b797ed3f5

+ 3
- 1
examples/vanilla/settings.py View File

@@ -63,6 +63,7 @@ MEDIA_URL = '/media/'
63 63
 # Examples: "http://foo.com/media/", "/media/".
64 64
 ADMIN_MEDIA_PREFIX = '/media/admin/'
65 65
 
66
+
66 67
 # Make this unique, and don't share it with anybody.
67 68
 SECRET_KEY = '$)a7n&o80u!6y5t-+jrd3)3!%vh&shg$wqpjpxc!ar&p#!)n1a'
68 69
 
@@ -180,10 +181,11 @@ INSTALLED_APPS = (
180 181
     'django.contrib.messages',
181 182
     'django.contrib.admin',
182 183
     'django.contrib.flatpages',
184
+    'django.contrib.staticfiles',
183 185
     # External apps
184 186
     'django_extensions',
185 187
     'haystack',
186
-    'debug_toolbar',
188
+    #'debug_toolbar',
187 189
     # Apps from oscar
188 190
     'oscar',
189 191
     'oscar.apps.analytics',

+ 3
- 8
examples/vanilla/templates/layout.html View File

@@ -20,11 +20,6 @@
20 20
                 <a href="{% url customer:login %}">Login</a>
21 21
             {% endif %}
22 22
             
23
-            Add a:
24
-            <a href="/admin/promotions/pagepromotion/add/?page_url={{ url_path }}" >promotion</a> /
25
-            <a href="/admin/promotions/pagemerchandisingblock/add/?page_url={{ url_path }}" >merchandising block</a>
26
-            to this page.
27
-            
28 23
             Basket total: {{ basket.total_incl_tax|currency }}
29 24
             <a href="{% url basket:summary %}">View basket</a>
30 25
             
@@ -42,9 +37,9 @@
42 37
             {% endif %}
43 38
             
44 39
             <div id="promotions">
45
-            {% for promotion in promotions_top %}
46
-                {% render_promotion promotion %}
47
-            {% endfor %}
40
+                {% for promotion in promotions_page %}
41
+                    {% render_promotion promotion %}
42
+                {% endfor %}
48 43
             </div>
49 44
             
50 45
             {% block content %}{% endblock %}

+ 4
- 0
examples/vanilla/urls.py View File

@@ -1,5 +1,7 @@
1 1
 from django.conf.urls.defaults import *
2 2
 from django.contrib import admin
3
+from django.conf.urls.static import static
4
+from django.conf import settings
3 5
 
4 6
 from oscar.app import shop
5 7
 
@@ -9,3 +11,5 @@ urlpatterns = patterns('',
9 11
     (r'^admin/', include(admin.site.urls)),
10 12
     (r'', include(shop.urls)),
11 13
 )
14
+if settings.DEBUG:
15
+    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

+ 4
- 3
oscar/apps/promotions/admin.py View File

@@ -1,6 +1,6 @@
1 1
 from django.contrib import admin
2 2
 
3
-from oscar.apps.promotions.models import Banner, Pod, HandPickedProductList, OrderedProduct, AutomaticProductList, TabbedBlock, \
3
+from oscar.apps.promotions.models import Image, MultiImage, RawHTML, HandPickedProductList, OrderedProduct, AutomaticProductList, TabbedBlock, \
4 4
                                   PagePromotion, KeywordPromotion
5 5
 
6 6
 
@@ -25,8 +25,9 @@ class KeywordPromotionAdmin(admin.ModelAdmin):
25 25
     readonly_fields = ['clicks']
26 26
 
27 27
 
28
-admin.site.register(Banner)
29
-admin.site.register(Pod)
28
+admin.site.register(Image)
29
+admin.site.register(MultiImage)
30
+admin.site.register(RawHTML)
30 31
 admin.site.register(HandPickedProductList, HandPickedProductListAdmin)
31 32
 admin.site.register(AutomaticProductList)
32 33
 admin.site.register(TabbedBlock)

+ 9
- 7
oscar/apps/promotions/context_processors.py View File

@@ -10,16 +10,18 @@ def promotions(request):
10 10
     For adding bindings for banners and pods to the template
11 11
     context.
12 12
     """
13
-    context = {
14
-        'url_path': request.path
15
-    }
13
+    
16 14
     # @todo need caching here / and order bt
17 15
     promotions = PagePromotion._default_manager.select_related().filter(page_url=request.path)
18 16
 
19
-    if 'q' in request.GET:
20
-        keyword_promotions = KeywordPromotion._default_manager.select_related().filter(keyword=request.GET['q'])
21
-        if keyword_promotions.count() > 0:
22
-            promotions = list(chain(promotions, keyword_promotions))
17
+#    if 'q' in request.GET:
18
+#        keyword_promotions = KeywordPromotion._default_manager.select_related().filter(keyword=request.GET['q'])
19
+#        if keyword_promotions.count() > 0:
20
+#            promotions = list(chain(promotions, keyword_promotions))
21
+
22
+    context = {
23
+        'url_path': request.path
24
+    }
23 25
 
24 26
     # Split the promotions into separate lists for each position, and 
25 27
     # add them to the template bindings

+ 31
- 25
oscar/apps/promotions/models.py View File

@@ -9,14 +9,10 @@ from django.contrib.contenttypes.models import ContentType
9 9
 
10 10
 from oscar.forms.fields import ExtendedURLField
11 11
 
12
-# Settings-controlled stuff
13
-BANNER_FOLDER = settings.OSCAR_BANNER_FOLDER
14
-POD_FOLDER = settings.OSCAR_POD_FOLDER
15
-
16 12
 # Different model types for each type of promotion
17 13
 
18 14
 
19
-class Promotion(models.Model):
15
+class AbstractPromotion(models.Model):
20 16
     """
21 17
     Abstract base promotion that defines the interface
22 18
     that subclasses must implement.
@@ -40,36 +36,50 @@ class Promotion(models.Model):
40 36
         return {}
41 37
 
42 38
 
43
-class Banner(Promotion):
39
+class RawHTML(AbstractPromotion):
40
+    """
41
+    Simple promotion - just raw HTML
42
+    """
43
+    name = models.CharField(_("Name"), max_length=128)
44
+    body = models.TextField(_("HTML"))
45
+    date_created = models.DateTimeField(auto_now_add=True)
46
+
47
+
48
+class Image(AbstractPromotion):
49
+    """
50
+    An image promotion is simply a named image which has an optional 
51
+    link to another part of the site (or another site).
44 52
     
53
+    This can be used to model both banners and pods.
54
+    """
45 55
     name = models.CharField(_("Name"), max_length=128)
46 56
     link_url = ExtendedURLField(blank=True, null=True, help_text="""This is 
47 57
         where this promotion links to""")
48
-    image = models.ImageField(upload_to=BANNER_FOLDER, blank=True, null=True)
58
+    image = models.ImageField(upload_to=settings.OSCAR_PROMOTION_FOLDER, blank=True, null=True)
49 59
     date_created = models.DateTimeField(auto_now_add=True)
50 60
     
51 61
     def __unicode__(self):
52 62
         return self.name
53 63
     
54
-
55
-class Pod(Promotion):
56 64
     
65
+class MultiImage(AbstractPromotion):
66
+    """
67
+    A multi-image promotion is simply a collection of image promotions
68
+    that are rendered in a specific way.  This models things like 
69
+    rotating banners.
70
+    """
57 71
     name = models.CharField(_("Name"), max_length=128)
58
-    link_url = ExtendedURLField(blank=True, null=True, help_text="""This is 
59
-        where this promotion links to""")
60
-    image = models.ImageField(upload_to=BANNER_FOLDER, blank=True, null=True)
61
-    date_created = models.DateTimeField(auto_now_add=True)
72
+    tabs = models.ManyToManyField('promotions.Image', null=True, blank=True)
62 73
     
63 74
     def __unicode__(self):
64 75
         return self.name
65 76
 
66 77
 
67
-class AbstractProductList(Promotion):
78
+class AbstractProductList(AbstractPromotion):
68 79
     """
69 80
     Abstract superclass for promotions which are essentially a list
70 81
     of products.
71 82
     """
72
-    
73 83
     name = models.CharField(_("Title"), max_length=255)
74 84
     description = models.TextField(null=True, blank=True)
75 85
     link_url = ExtendedURLField(blank=True, null=True)
@@ -83,7 +93,10 @@ class AbstractProductList(Promotion):
83 93
         
84 94
  
85 95
 class HandPickedProductList(AbstractProductList):
86
-    
96
+    """
97
+    A hand-picked product list is a list of manually selected
98
+    products.
99
+    """
87 100
     products = models.ManyToManyField('product.Item', through='OrderedProduct', blank=True, null=True)
88 101
     
89 102
 
@@ -118,7 +131,7 @@ class OrderedProductList(models.Model):
118 131
         ordering = ('display_order',)
119 132
 
120 133
 
121
-class TabbedBlock(Promotion):
134
+class TabbedBlock(AbstractPromotion):
122 135
 
123 136
     tabs = models.ManyToManyField('promotions.HandPickedProductList', through='OrderedProductList', null=True, blank=True)
124 137
     date_created = models.DateTimeField(auto_now_add=True)
@@ -126,13 +139,6 @@ class TabbedBlock(Promotion):
126 139
     
127 140
 # Linking models
128 141
 
129
-TOP, LEFT, RIGHT = ('Top', 'Left', 'Right')
130
-POSITION_CHOICES = (
131
-    (TOP, _("Top of page")),
132
-    (LEFT, _("Left-hand sidebar")),
133
-    (RIGHT, _("Right-hand sidebar")),
134
-)
135
-
136 142
 
137 143
 class LinkedPromotion(models.Model):
138 144
     
@@ -141,7 +147,7 @@ class LinkedPromotion(models.Model):
141 147
     object_id = models.PositiveIntegerField()
142 148
     content_object = generic.GenericForeignKey('content_type', 'object_id')
143 149
     
144
-    position = models.CharField(_("Position"), max_length=100, help_text="Position on page", choices=POSITION_CHOICES)
150
+    position = models.CharField(_("Position"), max_length=100, help_text="Position on page")
145 151
     display_order = models.PositiveIntegerField(default=0)
146 152
     clicks = models.PositiveIntegerField(default=0)
147 153
     date_created = models.DateTimeField(auto_now_add=True)

+ 2
- 2
oscar/apps/promotions/templatetags/promotions.py View File

@@ -6,10 +6,10 @@ register = Library()
6 6
      
7 7
 class PromotionNode(Node):
8 8
     def __init__(self, promotion):
9
-        self.promotion = Variable(promotion)
9
+        self.promotion_var = Variable(promotion)
10 10
     
11 11
     def render(self, context):
12
-        promotion = self.promotion.resolve(context)
12
+        promotion = self.promotion_var.resolve(context)
13 13
         template = select_template([promotion.template_name(), 'promotions/default.html'])
14 14
         args = dict(promotion=promotion, **promotion.template_context(request=context['request']))
15 15
         return template.render(Context(args))

+ 1
- 2
oscar/defaults.py View File

@@ -11,8 +11,7 @@ OSCAR_RECENTLY_VIEWED_PRODUCTS = 4
11 11
 
12 12
 # Image paths
13 13
 OSCAR_IMAGE_FOLDER = 'images/products/%Y/%m/'
14
-OSCAR_BANNER_FOLDER = 'images/promotions/banners'
15
-OSCAR_POD_FOLDER = 'images/promotions/pods'
14
+OSCAR_PROMOTION_FOLDER = 'images/promotions/'
16 15
 
17 16
 # Search settings
18 17
 OSCAR_SEARCH_SUGGEST_LIMIT = 10

+ 0
- 19
oscar/templates/base.html View File

@@ -1,19 +0,0 @@
1
-<!DOCTYPE html> 
2
-<html lang="{% block language %}en-gb{% endblock %}">
3
-    <head>
4
-        <title>{% block title %}Oscar :: Flexible ecommerce for Django{% endblock %}</title>
5
-        <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
6
-        <meta name="created" content='{% now "jS M Y h:i" %}' />
7
-        <meta name="description" content="{% block description %}{% endblock %}" />
8
-        <meta name="keywords" content="{% block keywords %}{% endblock %}" />
9
-        {% block extra_head %}{% endblock %}
10
-    </head>
11
-    <body id="{% block body_id %}default{% endblock %}" class="{% block body_class %}default{% endblock %}">
12
-        {% block layout %}{% endblock %}
13
-        {% block tracking %}
14
-            {% if not debug and not request.user.is_staff %}
15
-                <!-- Tracking to go here. -->
16
-            {% endif %}
17
-        {% endblock %}
18
-    </body>
19
-</html>

+ 0
- 56
oscar/templates/layout.html View File

@@ -1,56 +0,0 @@
1
-{% extends "base.html" %}
2
-
3
-{% load currency_filters %}
4
-{% load promotions %}
5
-
6
-{% block layout %}
7
-    <div id="container">
8
-        <div id="header">
9
-            <p><a href="{% url home %}">Oscar // Flexible e-commerce for Django</a></p>
10
-            
11
-            <form method="get" action="{% url search:search %}">
12
-                {{ search_form.as_p }}
13
-                <input type="submit" value="Go!" /> 
14
-            </form>
15
-            
16
-            {% if user.is_authenticated %}
17
-                <a href="{% url customer:summary %}">Profile</a>
18
-                <a href="{% url customer:logout %}">Logout</a>
19
-            {% else %}
20
-                <a href="{% url customer:login %}">Login</a>
21
-            {% endif %}
22
-            
23
-            {% for banner in banners %}
24
-                {{ banner.get_banner_html|safe }}
25
-            {% endfor %}
26
-
27
-            Add a:
28
-            <a href="/admin/promotions/pagepromotion/add/?page_url={{ url_path }}" >promotion</a> /
29
-            <a href="/admin/promotions/pagemerchandisingblock/add/?page_url={{ url_path }}" >merchandising block</a>
30
-            to this page.
31
-            
32
-            Basket total: {{ basket.total_incl_tax|currency }}
33
-            <a href="{% url basket:summary %}">View basket</a>
34
-            
35
-            {% block header %}
36
-            {% endblock %}
37
-        </div>
38
-        <div id="content">
39
-        
40
-            {% if messages %}
41
-            <ul class="messages">
42
-                {% for message in messages %}
43
-                <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
44
-                {% endfor %}
45
-            </ul>
46
-            {% endif %}
47
-            
48
-            {% for linked_block in merchandising_blocks %}
49
-                {% render_merchandising_block linked_block %}
50
-            {% endfor %}
51
-            
52
-            {% block content %}{% endblock %}
53
-        </div>
54
-        <div id="footer">{% block footer %}{% endblock %}</div>
55
-    </div>
56
-{% endblock %}

+ 6
- 0
oscar/templates/promotions/image.html View File

@@ -0,0 +1,6 @@
1
+{% if promotion.link_url %}
2
+    <a href="{{ promotion.link_url }}"><img src="{{ promotion.image.url }}" title="{{ promotion.name }}" /></a>
3
+{% else %}
4
+    <img src="{{ promotion.image.url }}" title="{{ promotion.name }}" />
5
+{% endif %}
6
+

Loading…
Cancel
Save