Merge lp:~mhall119/ubuntu-api-website/content-editing into lp:ubuntu-api-website
- content-editing
- Merge into trunk
Proposed by
Michael Hall
Status: | Merged |
---|---|
Approved by: | Michael Hall |
Approved revision: | no longer in the source branch. |
Merged at revision: | 42 |
Proposed branch: | lp:~mhall119/ubuntu-api-website/content-editing |
Merge into: | lp:ubuntu-api-website |
Diff against target: |
1089 lines (+761/-26) 24 files modified
developer_network/common/fixtures/auth_group.json (+1/-0) developer_network/common/management/commands/initdb.py (+62/-0) developer_network/common/templates/500.html (+10/-0) developer_network/common/templates/login_failure.html (+37/-0) developer_network/common/views.py (+27/-1) developer_network/settings.py (+19/-0) developer_network/urls.py (+30/-1) developer_network/web/static/css/site.css (+60/-22) developer_network/web/templates/web/article.html (+17/-0) developer_network/web/templates/web/distro.html (+20/-0) developer_network/web/templates/web/element.html (+9/-0) developer_network/web/templates/web/element_edit.html (+48/-0) developer_network/web/templates/web/namespace.html (+12/-0) developer_network/web/templates/web/namespace_edit.html (+48/-0) developer_network/web/templates/web/overview.html (+17/-0) developer_network/web/templates/web/page.html (+9/-0) developer_network/web/templates/web/page_edit.html (+25/-0) developer_network/web/templates/web/release.html (+17/-2) developer_network/web/templates/web/search.html (+2/-0) developer_network/web/templates/web/section_edit.html (+25/-0) developer_network/web/templates/web/topic_edit.html (+18/-0) developer_network/web/templates/web/version_edit.html (+23/-0) developer_network/web/views.py (+223/-0) requirements.txt (+2/-0) |
To merge this branch: | bzr merge lp:~mhall119/ubuntu-api-website/content-editing |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Michael Hall (community) | Approve | ||
Review via email: mp+193481@code.launchpad.net |
Commit message
Adds the ability to edit content on various pages, adds SSO support and gives members of ~api-website-devs edit permissions.
Description of the change
Adds the ability to edit content on various pages, adds SSO support and gives members of ~api-website-devs edit permissions.
To post a comment you must log in.
- 42. By Michael Hall
-
[r=Michael Hall] Adds the ability to edit content on various pages, adds SSO support and gives members of ~api-website-devs edit permissions.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added file 'developer_network/common/fixtures/auth_group.json' |
2 | --- developer_network/common/fixtures/auth_group.json 1970-01-01 00:00:00 +0000 |
3 | +++ developer_network/common/fixtures/auth_group.json 2013-10-31 19:44:44 +0000 |
4 | @@ -0,0 +1,1 @@ |
5 | +[{"pk": 1, "model": "auth.permission", "fields": {"codename": "add_permission", "name": "Can add permission", "content_type": 1}}, {"pk": 2, "model": "auth.permission", "fields": {"codename": "change_permission", "name": "Can change permission", "content_type": 1}}, {"pk": 3, "model": "auth.permission", "fields": {"codename": "delete_permission", "name": "Can delete permission", "content_type": 1}}, {"pk": 4, "model": "auth.permission", "fields": {"codename": "add_group", "name": "Can add group", "content_type": 2}}, {"pk": 5, "model": "auth.permission", "fields": {"codename": "change_group", "name": "Can change group", "content_type": 2}}, {"pk": 6, "model": "auth.permission", "fields": {"codename": "delete_group", "name": "Can delete group", "content_type": 2}}, {"pk": 7, "model": "auth.permission", "fields": {"codename": "add_user", "name": "Can add user", "content_type": 3}}, {"pk": 8, "model": "auth.permission", "fields": {"codename": "change_user", "name": "Can change user", "content_type": 3}}, {"pk": 9, "model": "auth.permission", "fields": {"codename": "delete_user", "name": "Can delete user", "content_type": 3}}, {"pk": 10, "model": "auth.permission", "fields": {"codename": "add_message", "name": "Can add message", "content_type": 4}}, {"pk": 11, "model": "auth.permission", "fields": {"codename": "change_message", "name": "Can change message", "content_type": 4}}, {"pk": 12, "model": "auth.permission", "fields": {"codename": "delete_message", "name": "Can delete message", "content_type": 4}}, {"pk": 13, "model": "auth.permission", "fields": {"codename": "add_contenttype", "name": "Can add content type", "content_type": 5}}, {"pk": 14, "model": "auth.permission", "fields": {"codename": "change_contenttype", "name": "Can change content type", "content_type": 5}}, {"pk": 15, "model": "auth.permission", "fields": {"codename": "delete_contenttype", "name": "Can delete content type", "content_type": 5}}, {"pk": 16, "model": "auth.permission", "fields": {"codename": "add_session", "name": "Can add session", "content_type": 6}}, {"pk": 17, "model": "auth.permission", "fields": {"codename": "change_session", "name": "Can change session", "content_type": 6}}, {"pk": 18, "model": "auth.permission", "fields": {"codename": "delete_session", "name": "Can delete session", "content_type": 6}}, {"pk": 19, "model": "auth.permission", "fields": {"codename": "add_site", "name": "Can add site", "content_type": 7}}, {"pk": 20, "model": "auth.permission", "fields": {"codename": "change_site", "name": "Can change site", "content_type": 7}}, {"pk": 21, "model": "auth.permission", "fields": {"codename": "delete_site", "name": "Can delete site", "content_type": 7}}, {"pk": 22, "model": "auth.permission", "fields": {"codename": "add_logentry", "name": "Can add log entry", "content_type": 8}}, {"pk": 23, "model": "auth.permission", "fields": {"codename": "change_logentry", "name": "Can change log entry", "content_type": 8}}, {"pk": 24, "model": "auth.permission", "fields": {"codename": "delete_logentry", "name": "Can delete log entry", "content_type": 8}}, {"pk": 25, "model": "auth.permission", "fields": {"codename": "add_migrationhistory", "name": "Can add migration history", "content_type": 9}}, {"pk": 26, "model": "auth.permission", "fields": {"codename": "change_migrationhistory", "name": "Can change migration history", "content_type": 9}}, {"pk": 27, "model": "auth.permission", "fields": {"codename": "delete_migrationhistory", "name": "Can delete migration history", "content_type": 9}}, {"pk": 28, "model": "auth.permission", "fields": {"codename": "add_topic", "name": "Can add topic", "content_type": 10}}, {"pk": 29, "model": "auth.permission", "fields": {"codename": "change_topic", "name": "Can change topic", "content_type": 10}}, {"pk": 30, "model": "auth.permission", "fields": {"codename": "delete_topic", "name": "Can delete topic", "content_type": 10}}, {"pk": 31, "model": "auth.permission", "fields": {"codename": "add_version", "name": "Can add version", "content_type": 11}}, {"pk": 32, "model": "auth.permission", "fields": {"codename": "change_version", "name": "Can change version", "content_type": 11}}, {"pk": 33, "model": "auth.permission", "fields": {"codename": "delete_version", "name": "Can delete version", "content_type": 11}}, {"pk": 34, "model": "auth.permission", "fields": {"codename": "add_section", "name": "Can add section", "content_type": 12}}, {"pk": 35, "model": "auth.permission", "fields": {"codename": "change_section", "name": "Can change section", "content_type": 12}}, {"pk": 36, "model": "auth.permission", "fields": {"codename": "delete_section", "name": "Can delete section", "content_type": 12}}, {"pk": 37, "model": "auth.permission", "fields": {"codename": "add_namespace", "name": "Can add namespace", "content_type": 13}}, {"pk": 38, "model": "auth.permission", "fields": {"codename": "change_namespace", "name": "Can change namespace", "content_type": 13}}, {"pk": 39, "model": "auth.permission", "fields": {"codename": "delete_namespace", "name": "Can delete namespace", "content_type": 13}}, {"pk": 40, "model": "auth.permission", "fields": {"codename": "add_element", "name": "Can add Rendered Element", "content_type": 14}}, {"pk": 41, "model": "auth.permission", "fields": {"codename": "change_element", "name": "Can change Rendered Element", "content_type": 14}}, {"pk": 42, "model": "auth.permission", "fields": {"codename": "delete_element", "name": "Can delete Rendered Element", "content_type": 14}}, {"pk": 43, "model": "auth.permission", "fields": {"codename": "add_class", "name": "Can add class", "content_type": 15}}, {"pk": 44, "model": "auth.permission", "fields": {"codename": "change_class", "name": "Can change class", "content_type": 15}}, {"pk": 45, "model": "auth.permission", "fields": {"codename": "delete_class", "name": "Can delete class", "content_type": 15}}, {"pk": 46, "model": "auth.permission", "fields": {"codename": "add_bitfield", "name": "Can add bit field", "content_type": 16}}, {"pk": 47, "model": "auth.permission", "fields": {"codename": "change_bitfield", "name": "Can change bit field", "content_type": 16}}, {"pk": 48, "model": "auth.permission", "fields": {"codename": "delete_bitfield", "name": "Can delete bit field", "content_type": 16}}, {"pk": 49, "model": "auth.permission", "fields": {"codename": "add_enum", "name": "Can add enum", "content_type": 17}}, {"pk": 50, "model": "auth.permission", "fields": {"codename": "change_enum", "name": "Can change enum", "content_type": 17}}, {"pk": 51, "model": "auth.permission", "fields": {"codename": "delete_enum", "name": "Can delete enum", "content_type": 17}}, {"pk": 52, "model": "auth.permission", "fields": {"codename": "add_snippet", "name": "Can add snippet", "content_type": 18}}, {"pk": 53, "model": "auth.permission", "fields": {"codename": "change_snippet", "name": "Can change snippet", "content_type": 18}}, {"pk": 54, "model": "auth.permission", "fields": {"codename": "delete_snippet", "name": "Can delete snippet", "content_type": 18}}, {"pk": 55, "model": "auth.permission", "fields": {"codename": "add_image", "name": "Can add image", "content_type": 19}}, {"pk": 56, "model": "auth.permission", "fields": {"codename": "change_image", "name": "Can change image", "content_type": 19}}, {"pk": 57, "model": "auth.permission", "fields": {"codename": "delete_image", "name": "Can delete image", "content_type": 19}}, {"pk": 58, "model": "auth.permission", "fields": {"codename": "add_link", "name": "Can add link", "content_type": 20}}, {"pk": 59, "model": "auth.permission", "fields": {"codename": "change_link", "name": "Can change link", "content_type": 20}}, {"pk": 60, "model": "auth.permission", "fields": {"codename": "delete_link", "name": "Can delete link", "content_type": 20}}, {"pk": 61, "model": "auth.permission", "fields": {"codename": "add_page", "name": "Can add Rendered Page", "content_type": 21}}, {"pk": 62, "model": "auth.permission", "fields": {"codename": "change_page", "name": "Can change Rendered Page", "content_type": 21}}, {"pk": 63, "model": "auth.permission", "fields": {"codename": "delete_page", "name": "Can delete Rendered Page", "content_type": 21}}, {"pk": 64, "model": "auth.permission", "fields": {"codename": "add_nonce", "name": "Can add nonce", "content_type": 22}}, {"pk": 65, "model": "auth.permission", "fields": {"codename": "change_nonce", "name": "Can change nonce", "content_type": 22}}, {"pk": 66, "model": "auth.permission", "fields": {"codename": "delete_nonce", "name": "Can delete nonce", "content_type": 22}}, {"pk": 67, "model": "auth.permission", "fields": {"codename": "add_association", "name": "Can add association", "content_type": 23}}, {"pk": 68, "model": "auth.permission", "fields": {"codename": "change_association", "name": "Can change association", "content_type": 23}}, {"pk": 69, "model": "auth.permission", "fields": {"codename": "delete_association", "name": "Can delete association", "content_type": 23}}, {"pk": 70, "model": "auth.permission", "fields": {"codename": "add_useropenid", "name": "Can add user open id", "content_type": 24}}, {"pk": 71, "model": "auth.permission", "fields": {"codename": "change_useropenid", "name": "Can change user open id", "content_type": 24}}, {"pk": 72, "model": "auth.permission", "fields": {"codename": "delete_useropenid", "name": "Can delete user open id", "content_type": 24}}, {"pk": 1, "model": "auth.group", "fields": {"name": "api-website-devs", "permissions": [40, 41, 42, 37, 38, 39, 61, 62, 63, 34, 35, 36, 28, 29, 30, 31, 32, 33, 55, 56, 57, 58, 59, 60, 52, 53, 54, 46, 47, 48, 43, 44, 45, 49, 50, 51]}}] |
6 | \ No newline at end of file |
7 | |
8 | === added directory 'developer_network/common/management' |
9 | === added file 'developer_network/common/management/__init__.py' |
10 | === added directory 'developer_network/common/management/commands' |
11 | === added file 'developer_network/common/management/commands/__init__.py' |
12 | === added file 'developer_network/common/management/commands/initdb.py' |
13 | --- developer_network/common/management/commands/initdb.py 1970-01-01 00:00:00 +0000 |
14 | +++ developer_network/common/management/commands/initdb.py 2013-10-31 19:44:44 +0000 |
15 | @@ -0,0 +1,62 @@ |
16 | +#!/usr/bin/python |
17 | + |
18 | +from django.core.management.base import BaseCommand |
19 | +from optparse import make_option |
20 | + |
21 | +import settings |
22 | + |
23 | +import subprocess |
24 | +import os |
25 | +import sys |
26 | + |
27 | +from common.models import Topic |
28 | +from apidocs.models import Element |
29 | +from django.contrib.auth.models import Group, Permission |
30 | +from django.contrib.contenttypes.models import ContentType |
31 | + |
32 | +PYTHON_BIN = sys.executable |
33 | +PROJECT_ROOT = os.path.normpath(os.path.join(os.path.dirname(__file__), '../../../')) |
34 | +MANAGE_PY = os.path.join(PROJECT_ROOT, 'manage.py') |
35 | +COMMON_DATA = os.path.join(PROJECT_ROOT, 'common/fixtures/sample_data.json') |
36 | +APIDOCS_DATA = os.path.join(PROJECT_ROOT, 'apidocs/fixtures/sample_data.json') |
37 | + |
38 | + |
39 | +class Command(BaseCommand): |
40 | + help = "Make sure The API Website database is set up properly." |
41 | + option_list = BaseCommand.option_list + ( |
42 | + make_option( |
43 | + "-f", |
44 | + "--force", |
45 | + dest="force", |
46 | + help="Force initialization, even if data already exists", |
47 | + action="store_true", |
48 | + default=False |
49 | + ), |
50 | + ) |
51 | + |
52 | + def handle(self, summit='', *args, **options): |
53 | + |
54 | + force = options.get('force', False) |
55 | + |
56 | + if force or Topic.objects.all().count() == 0: |
57 | + print "Loading Common data." |
58 | + subprocess.call([PYTHON_BIN, MANAGE_PY, "loaddata", COMMON_DATA, |
59 | + "--settings", "local_settings"]) |
60 | + |
61 | + if force or Element.objects.all().count() == 0: |
62 | + print "Loading API data." |
63 | + subprocess.call([PYTHON_BIN, MANAGE_PY, "loaddata", APIDOCS_DATA, |
64 | + "--settings", "local_settings"]) |
65 | + |
66 | + if force or not Group.objects.filter(name='api-website-devs').exists(): |
67 | + print "Creating api-website-devs group." |
68 | + devs, created = Group.objects.get_or_create(name='api-website-devs') |
69 | + common_perms = Permission.objects.filter(content_type__app_label='common') |
70 | + apidocs_perms = Permission.objects.filter(content_type__app_label='apidocs') |
71 | + related_perms = Permission.objects.filter(content_type__app_label='related') |
72 | + search_perms = Permission.objects.filter(content_type__app_label='search') |
73 | + devs.permissions.add(*list(common_perms)) |
74 | + devs.permissions.add(*list(apidocs_perms)) |
75 | + devs.permissions.add(*list(related_perms)) |
76 | + devs.permissions.add(*list(search_perms)) |
77 | + |
78 | |
79 | === added directory 'developer_network/common/templates' |
80 | === added file 'developer_network/common/templates/500.html' |
81 | --- developer_network/common/templates/500.html 1970-01-01 00:00:00 +0000 |
82 | +++ developer_network/common/templates/500.html 2013-10-31 19:44:44 +0000 |
83 | @@ -0,0 +1,10 @@ |
84 | +{% extends "base.html" %} |
85 | + |
86 | +{% block page_name %}Oops{%endblock %} |
87 | + |
88 | +{% block sub_nav %}{% endblock %} |
89 | + |
90 | +{% block content %} |
91 | +<p>This page encountered an error, don't worry - we have been notified. Please accept our apologies.</p> |
92 | +{% endblock %} |
93 | + |
94 | |
95 | === added file 'developer_network/common/templates/login_failure.html' |
96 | --- developer_network/common/templates/login_failure.html 1970-01-01 00:00:00 +0000 |
97 | +++ developer_network/common/templates/login_failure.html 2013-10-31 19:44:44 +0000 |
98 | @@ -0,0 +1,37 @@ |
99 | +{% extends "base.html" %} |
100 | + |
101 | +{% block page_name %}Login Failure{%endblock %} |
102 | + |
103 | +{% block defaulthead %} |
104 | +{% with '/static/ubuntu-website/' as ubuntu_website_media %} |
105 | +{{ block.super }} |
106 | +{% endwith %} |
107 | +{% endblock %} |
108 | + |
109 | +{% block extrahead %} |
110 | +{% with '/static/' as MEDIA_URL %} |
111 | +{{ block.super }} |
112 | +{% endwith %} |
113 | +{% endblock %} |
114 | +{% block main_nav_links %}{% endblock %} |
115 | + |
116 | +{% block sub_nav %}{% endblock %} |
117 | + |
118 | +{% block content %} |
119 | + |
120 | +<article class="main-content"> |
121 | + <h2>{{message|safe}}</h2> |
122 | + |
123 | + {% if exception %} |
124 | + <p>{{exception.message|safe}}</p> |
125 | + {% endif %} |
126 | + |
127 | + {% if solution %} |
128 | + <p>{{solution|safe}}</p> |
129 | + {% endif %} |
130 | + |
131 | + <p>If you continue to experience problems with Summit, please <a href='https://bugs.launchpad.net/summit'>Report it!</a> |
132 | + </p> |
133 | +</article> |
134 | + |
135 | +{% endblock %} |
136 | |
137 | === modified file 'developer_network/common/views.py' |
138 | --- developer_network/common/views.py 2013-02-08 22:36:08 +0000 |
139 | +++ developer_network/common/views.py 2013-10-31 19:44:44 +0000 |
140 | @@ -1,1 +1,27 @@ |
141 | -# Create your views here. |
142 | +from django.shortcuts import render_to_response, redirect |
143 | +from django.template.loader import render_to_string |
144 | +from django.template import RequestContext |
145 | +from django.http import HttpResponse, HttpResponseRedirect |
146 | +from django.core.urlresolvers import reverse |
147 | +from django.contrib.auth import logout |
148 | + |
149 | +def login_failure(request, message, status=403, |
150 | + template_name='login_failure.html', |
151 | + exception=None): |
152 | + """Render an error page to the user.""" |
153 | + context = { |
154 | + 'message': message, |
155 | + 'exception': exception, |
156 | + } |
157 | + if isinstance(exception, MissingPhysicalMultiFactor): |
158 | + context['solution'] = 'Try logging in again using your Yubikey' |
159 | + elif isinstance(exception, MissingUsernameViolation): |
160 | + context['solution'] = 'You will need to create a <a href="https://launchpad.net/people/+me">Launchpad profile</a> to use The API Website' |
161 | + |
162 | + data = render_to_string(template_name, context, |
163 | + context_instance=RequestContext(request)) |
164 | + return HttpResponse(data, status=status) |
165 | + |
166 | +def logout_view(request): |
167 | + logout(request) |
168 | + return HttpResponseRedirect('/') |
169 | |
170 | === modified file 'developer_network/settings.py' |
171 | --- developer_network/settings.py 2013-09-13 18:35:01 +0000 |
172 | +++ developer_network/settings.py 2013-10-31 19:44:44 +0000 |
173 | @@ -128,6 +128,7 @@ |
174 | 'related', |
175 | 'web', |
176 | 'ubuntu_website', |
177 | + 'django_openid_auth', |
178 | ) |
179 | |
180 | # A sample logging configuration. The only tangible logging |
181 | @@ -152,3 +153,21 @@ |
182 | }, |
183 | } |
184 | } |
185 | + |
186 | +AUTHENTICATION_BACKENDS = ( |
187 | + 'django_openid_auth.auth.OpenIDBackend', |
188 | + 'django.contrib.auth.backends.ModelBackend', |
189 | +) |
190 | +# OPENID Related settings |
191 | +OPENID_STRICT_USERNAMES = True |
192 | +OPENID_FOLLOW_RENAMES = True |
193 | +OPENID_SREG_REQUIRED_FIELDS = ['email'] |
194 | +OPENID_CREATE_USERS = True |
195 | +OPENID_REUSE_USERS = True |
196 | +OPENID_UPDATE_DETAILS_FROM_SREG = True |
197 | +OPENID_SSO_SERVER_URL = 'https://login.ubuntu.com/' |
198 | +OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO = True |
199 | + |
200 | +# Tell django.contrib.auth to use the OpenID signin URLs. |
201 | +LOGIN_URL = '/api/login' |
202 | +LOGIN_REDIRECT_URL = '/' |
203 | |
204 | === modified file 'developer_network/urls.py' |
205 | --- developer_network/urls.py 2013-10-04 19:56:27 +0000 |
206 | +++ developer_network/urls.py 2013-10-31 19:44:44 +0000 |
207 | @@ -8,6 +8,16 @@ |
208 | from django.contrib.staticfiles.urls import staticfiles_urlpatterns |
209 | urlpatterns = staticfiles_urlpatterns() |
210 | |
211 | +from common.views import login_failure |
212 | +urlpatterns += patterns( |
213 | + 'django_openid_auth.views', |
214 | + url(r'^api/login/$', 'login_begin', name='openid-login', |
215 | + kwargs={'render_failure': login_failure}), |
216 | + url(r'^api/openid/complete/$', 'login_complete', name='openid-complete', |
217 | + kwargs={'render_failure': login_failure}), |
218 | + url(r'^api/openid/logo.gif$', 'logo', name='openid-logo'), |
219 | +) |
220 | + |
221 | urlpatterns += patterns('', |
222 | # Examples: |
223 | # url(r'^developer_network/', include('developer_network.foo.urls')), |
224 | @@ -17,14 +27,33 @@ |
225 | |
226 | # Uncomment the next line to enable the admin: |
227 | url(r'^api/admin/', include(admin.site.urls)), |
228 | + url(r'^api/logout/$', 'common.views.logout_view', name='logout'), |
229 | |
230 | url(r'^$', 'web.views.overview', name='overview'), |
231 | url(r'^api/$', 'web.views.overview', name='overview'), |
232 | + |
233 | url(r'^api/(?P<topic_name>[\w\.-]+)/$', 'web.views.topic_view', name='topic'), |
234 | + url(r'^api/\+topic/$', 'web.views.topic_edit', name='topic_edit'), |
235 | + url(r'^api/\+topic/(?P<topic_id>[\d]+)/$', 'web.views.topic_edit', name='topic_edit'), |
236 | + |
237 | url(r'^api/(?P<topic_name>[\w\.-]+)/(?P<release_version>[\w\.-]+)/$', 'web.views.version_view', name='version'), |
238 | + url(r'^api/(?P<topic_name>[\w\.-]+)/\+version/$', 'web.views.version_edit', name='version_edit'), |
239 | + url(r'^api/(?P<topic_name>[\w\.-]+)/\+version/(?P<version_id>[\d]+)/$', 'web.views.version_edit', name='version_edit'), |
240 | + |
241 | + url(r'^api/(?P<topic_name>[\w\.-]+)/(?P<version_name>[\w\.-]+)/\+section/(?P<section_id>[\d]+)/$', 'web.views.section_edit', name='section_edit'), |
242 | + url(r'^api/(?P<topic_name>[\w\.-]+)/(?P<version_name>[\w\.-]+)/\+section/$', 'web.views.section_edit', name='section_edit'), |
243 | + |
244 | + url(r'^api/(?P<topic_name>[\w\.-]+)/(?P<version_name>[\w\.-]+)/\+namespace/(?P<namespace_id>[\d]+)/$', 'web.views.namespace_edit', name='namespace_edit'), |
245 | + url(r'^api/(?P<topic_name>[\w\.-]+)/(?P<version_name>[\w\.-]+)/\+namespace/$', 'web.views.namespace_edit', name='namespace_edit'), |
246 | + |
247 | url(r'^api/(?P<topic_name>[\w\.-]+)/(?P<release_version>[\w\.-]+)/search/$', 'web.views.search', name='search'), |
248 | |
249 | - url(r'^api/(?P<topic_name>[\w\.-]+)/(?P<release_version>[\w\.-]+)/(?P<element_fullname>[\w\.\-\:]+).html$', 'web.views.element_view', name='element'), |
250 | url(r'^api/(?P<topic_name>[\w\.-]+)/(?P<release_version>[\w\.-]+)/(?P<element_fullname>[\w\.\-\:]+)/$', 'web.views.element_view', name='element'), |
251 | + url(r'^api/(?P<topic_name>[\w\.-]+)/(?P<release_version>[\w\.-]+)/\+element/(?P<element_id>[\d]+)/$', 'web.views.element_edit', name='element_edit'), |
252 | + url(r'^api/(?P<topic_name>[\w\.-]+)/(?P<release_version>[\w\.-]+)/\+element/$', 'web.views.element_edit', name='element_edit'), |
253 | + url(r'^api/(?P<topic_name>[\w\.-]+)/(?P<release_version>[\w\.-]+)/\+page/(?P<page_id>[\d]+)/$', 'web.views.page_edit', name='page_edit'), |
254 | + url(r'^api/(?P<topic_name>[\w\.-]+)/(?P<release_version>[\w\.-]+)/\+page/$', 'web.views.page_edit', name='page_edit'), |
255 | |
256 | ) |
257 | + |
258 | + |
259 | |
260 | === modified file 'developer_network/web/static/css/site.css' |
261 | --- developer_network/web/static/css/site.css 2013-10-22 20:54:40 +0000 |
262 | +++ developer_network/web/static/css/site.css 2013-10-31 19:44:44 +0000 |
263 | @@ -21,6 +21,25 @@ |
264 | display: inline; |
265 | } |
266 | |
267 | +#editor_actions { |
268 | + background-color: #F1F1F1; |
269 | + padding: 5px; |
270 | + margin-bottom: 10px; |
271 | + /* border-bottom: 1px dotted; */ |
272 | +} |
273 | + |
274 | +#editor_actions ul { |
275 | + margin: 0px; |
276 | +} |
277 | + |
278 | +#editor_actions li { |
279 | + margin-right: 10px; |
280 | + margin-bottom: 0; |
281 | + line-height: 33px; |
282 | + float: left; |
283 | + list-style: none; |
284 | + list-style-image: none; |
285 | +} |
286 | /* |
287 | * release.html |
288 | */ |
289 | @@ -47,6 +66,16 @@ |
290 | border-top: 1px dotted; |
291 | } |
292 | |
293 | +.section_title A.section_editor_action { |
294 | + float: right; |
295 | + font-size: .7em; |
296 | + display: none; |
297 | +} |
298 | + |
299 | +.section_title:hover A.section_editor_action { |
300 | + display: inherit; |
301 | +} |
302 | + |
303 | /* |
304 | * element.html |
305 | */ |
306 | @@ -75,54 +104,63 @@ |
307 | padding: 3px; |
308 | } |
309 | |
310 | +/* |
311 | + * element.html |
312 | +*/ |
313 | +#element_content TEXTAREA { |
314 | + height: inherit; |
315 | + width: inherit; |
316 | + max-width: none; |
317 | + max-height: none; |
318 | +} |
319 | /* |
320 | * sidenav.html |
321 | */ |
322 | |
323 | .ui-state-focus { |
324 | - outline: none; |
325 | + outline: none; |
326 | } |
327 | .ui-accordion { |
328 | - border-bottom: 1px dotted #aea79f; |
329 | + border-bottom: 1px dotted #aea79f; |
330 | } |
331 | .ui-accordion a { |
332 | - display: block; |
333 | + display: block; |
334 | } |
335 | .ui-accordion h3 { |
336 | - margin-bottom: 0; |
337 | - border-top: 1px dotted #aea79f; |
338 | - position: relative; |
339 | - font-size: 13px; |
340 | - font-weight: bold; |
341 | + margin-bottom: 0; |
342 | + border-top: 1px dotted #aea79f; |
343 | + position: relative; |
344 | + font-size: 13px; |
345 | + font-weight: bold; |
346 | } |
347 | .ui-accordion h3 a { |
348 | - padding: 10px 0; |
349 | - color: #333; |
350 | + padding: 10px 0; |
351 | + color: #333; |
352 | } |
353 | .ui-accordion h4 { |
354 | - margin-bottom: 5px; |
355 | + margin-bottom: 5px; |
356 | } |
357 | .ui-accordion div fieldset { |
358 | - padding-bottom: 5px; |
359 | + padding-bottom: 5px; |
360 | } |
361 | .ui-accordion div li, |
362 | .ui-accordion div input { |
363 | - margin-bottom: 10px; |
364 | + margin-bottom: 10px; |
365 | } |
366 | .ui-accordion .ui-icon { |
367 | - position: absolute; |
368 | - top: 15px; |
369 | - right: 0; |
370 | - display: block; |
371 | - width: 8px; |
372 | - height: 8px; |
373 | - background: url("../img/icon-accordion-inactive.png") 0 0 no-repeat transparent; |
374 | + position: absolute; |
375 | + top: 15px; |
376 | + right: 0; |
377 | + display: block; |
378 | + width: 8px; |
379 | + height: 8px; |
380 | + background: url("../img/icon-accordion-inactive.png") 0 0 no-repeat transparent; |
381 | } |
382 | .ui-accordion .ui-state-active .ui-icon { |
383 | - background-image: url("../img/icon-accordion-active.png"); |
384 | + background-image: url("../img/icon-accordion-active.png"); |
385 | } |
386 | .ui-accordion .current_page_item a { |
387 | - color: #333; |
388 | + color: #333; |
389 | } |
390 | |
391 | /* |
392 | |
393 | === modified file 'developer_network/web/templates/web/article.html' |
394 | --- developer_network/web/templates/web/article.html 2013-09-23 21:27:54 +0000 |
395 | +++ developer_network/web/templates/web/article.html 2013-10-31 19:44:44 +0000 |
396 | @@ -26,6 +26,23 @@ |
397 | {% endblock %} |
398 | </span> |
399 | </section> |
400 | + {% block editor_actions %} |
401 | + {% if perms.common or perms.apidocs %} |
402 | + <section id="editor_actions"> |
403 | + <span style="float: right;"> |
404 | + <ul class="clearfix"> |
405 | + <li><a href="{% url logout %}" title="You are logged in as: {{user.username}}">Logout</a></li> |
406 | + </ul> |
407 | + </span> |
408 | + <span id="editor_links"> |
409 | + <ul class="clearfix"> |
410 | + {% block editor_links %} |
411 | + {% endblock %} |
412 | + </ul> |
413 | + </span> |
414 | + </section> |
415 | + {% endif %} |
416 | + {% endblock %} |
417 | <article> |
418 | {% block article_content %} |
419 | {% endblock %} |
420 | |
421 | === modified file 'developer_network/web/templates/web/distro.html' |
422 | --- developer_network/web/templates/web/distro.html 2013-09-13 14:01:30 +0000 |
423 | +++ developer_network/web/templates/web/distro.html 2013-10-31 19:44:44 +0000 |
424 | @@ -3,6 +3,26 @@ |
425 | {% block sub_nav %}{% endblock %} |
426 | |
427 | {% block content %} |
428 | +{% if perms.common %} |
429 | +<section id="editor_actions"> |
430 | + <span style="float: right;"> |
431 | + <ul class="clearfix"> |
432 | + <li><a href="{% url logout %}" title="You are logged in as: {{user.username}}">Logout</a></li> |
433 | + </ul> |
434 | + </span> |
435 | + <span id="editor_links"> |
436 | + <ul class="clearfix"> |
437 | + {% if perms.common.change_topic %} |
438 | + <li><a href="{% url topic_edit topic.id %}">Edit</a></li> |
439 | + {% endif %} |
440 | + {% if perms.common.add_version %} |
441 | + <li><a href="{% url version_edit topic.slug %}">+ Version</a></li> |
442 | + {% endif %} |
443 | + </ul> |
444 | + </span> |
445 | +</section> |
446 | +{% endif %} |
447 | + |
448 | <h2>{{topic.name}} Versions</h2> |
449 | <ul> |
450 | {% for version in topic.version_set.all %} |
451 | |
452 | === modified file 'developer_network/web/templates/web/element.html' |
453 | --- developer_network/web/templates/web/element.html 2013-09-19 17:48:26 +0000 |
454 | +++ developer_network/web/templates/web/element.html 2013-10-31 19:44:44 +0000 |
455 | @@ -1,5 +1,14 @@ |
456 | {% extends "web/article.html" %} |
457 | |
458 | +{% block editor_links %} |
459 | + {% if perms.apidocs.change_element %} |
460 | + <li><a href="{% url element_edit topic.slug, version.slug, element.id %}">Edit</a></li> |
461 | + {% endif %} |
462 | + {% if perms.apidocs.delete_element %} |
463 | + <li><a href="{% url element_edit topic.slug, version.slug, element.id %}?action=delete">Delete</a></li> |
464 | + {% endif %} |
465 | +{% endblock %} |
466 | + |
467 | {% block breadcrumbs %} |
468 | <li><a class="sub-nav-item" href="{% url topic element.platform_section.topic_version.topic.slug %}">{{element.platform_section.topic_version.topic.name}}</a></li> |
469 | <li> › <a class="sub-nav-item" href="{% url version element.platform_section.topic_version.topic.slug element.platform_section.topic_version.slug %}">{{element.platform_section.topic_version.name}}</a></li> |
470 | |
471 | === added file 'developer_network/web/templates/web/element_edit.html' |
472 | --- developer_network/web/templates/web/element_edit.html 1970-01-01 00:00:00 +0000 |
473 | +++ developer_network/web/templates/web/element_edit.html 2013-10-31 19:44:44 +0000 |
474 | @@ -0,0 +1,48 @@ |
475 | +{% extends "web/article.html" %} |
476 | + |
477 | +{% block editor_links %} |
478 | + {% if element.id and perms.apidocs.delete_element %} |
479 | + <li><a href="{% url element_edit topic.slug version.slug element.id %}?action=delete">Delete</a></li> |
480 | + {% endif %} |
481 | +{% endblock %} |
482 | + |
483 | +{% block breadcrumbs %} |
484 | +{% endblock %} |
485 | + |
486 | +{% block article_content %} |
487 | +{% if element.id %} |
488 | +<h1>Edit: {{element.name}}</h1> |
489 | +{% else %} |
490 | +<h1>New Element</h1> |
491 | +{% endif %} |
492 | + |
493 | +<form action="" method="POST" id="element_form"> |
494 | +{% csrf_token %} |
495 | +<div id="element_content"> |
496 | +{{ form.as_p }} |
497 | +</div> |
498 | +<input type="submit" value="Save"> |
499 | +</form> |
500 | + |
501 | +{% comment %} |
502 | +<h3>Snippets</h3> |
503 | +{% for snippet in snippets %} |
504 | + <div> |
505 | + <li>{{ snippet.name }}</li> |
506 | + </div> |
507 | +{% endfor %} |
508 | + |
509 | +<h3>Questions & Answers</h3> |
510 | +{% for question in questions %} |
511 | + <div> |
512 | + <li><a href="{{ question.url }}">{{ question.name }}</a></li> |
513 | + </div> |
514 | +{% endfor %} |
515 | +<h3>Tutorials</h3> |
516 | +{% for tutorial in tutorials %} |
517 | + <div> |
518 | + <li><a href="{{ tutorial.url }}">{{ tutorial.name }}</a></li> |
519 | + </div> |
520 | +{% endfor %} |
521 | +{% endcomment %} |
522 | +{% endblock %} |
523 | |
524 | === modified file 'developer_network/web/templates/web/namespace.html' |
525 | --- developer_network/web/templates/web/namespace.html 2013-10-04 19:56:27 +0000 |
526 | +++ developer_network/web/templates/web/namespace.html 2013-10-31 19:44:44 +0000 |
527 | @@ -1,5 +1,17 @@ |
528 | {% extends "web/article.html" %} |
529 | |
530 | +{% block editor_links %} |
531 | + {% if perms.apidocs.change_namespace %} |
532 | + <li><a href="{% url namespace_edit version.topic.slug version.slug namespace.id%}">Edit</a></li> |
533 | + {% endif %} |
534 | + {% if perms.apidocs.add_element %} |
535 | + <li><a href="{% url element_edit version.topic.slug version.slug %}">+ Element</a></li> |
536 | + {% endif %} |
537 | + {% if perms.apidocs.add_page %} |
538 | + <li><a href="{% url page_edit version.topic.slug version.slug %}">+ Page</a></li> |
539 | + {% endif %} |
540 | +{% endblock %} |
541 | + |
542 | {% block breadcrumbs %} |
543 | <li><a class="sub-nav-item" href="{% url topic namespace.platform_section.topic_version.topic.slug %}">{{namespace.platform_section.topic_version.topic.name}}</a></li> |
544 | <li> › <a class="sub-nav-item" href="{% url version namespace.platform_section.topic_version.topic.slug namespace.platform_section.topic_version.slug %}">{{namespace.platform_section.topic_version.name}}</a></li> |
545 | |
546 | === added file 'developer_network/web/templates/web/namespace_edit.html' |
547 | --- developer_network/web/templates/web/namespace_edit.html 1970-01-01 00:00:00 +0000 |
548 | +++ developer_network/web/templates/web/namespace_edit.html 2013-10-31 19:44:44 +0000 |
549 | @@ -0,0 +1,48 @@ |
550 | +{% extends "web/article.html" %} |
551 | + |
552 | +{% block editor_links %} |
553 | + {% if namespace.id and perms.apidocs.delete_namespace %} |
554 | + <li><a href="{% url namespace_edit topic.slug version.slug namespace.id %}?action=delete">Delete</a></li> |
555 | + {% endif %} |
556 | +{% endblock %} |
557 | + |
558 | +{% block breadcrumbs %} |
559 | +{% endblock %} |
560 | + |
561 | +{% block article_content %} |
562 | +{% if namespace.id %} |
563 | +<h1>Edit: {{namespace.name}}</h1> |
564 | +{% else %} |
565 | +<h1>New Namespace</h1> |
566 | +{% endif %} |
567 | + |
568 | +<form action="" method="POST" id="namespace_form"> |
569 | +{% csrf_token %} |
570 | +<div id="namespace_content"> |
571 | +{{ form.as_p }} |
572 | +</div> |
573 | +<input type="submit" value="Save"> |
574 | +</form> |
575 | + |
576 | +{% comment %} |
577 | +<h3>Snippets</h3> |
578 | +{% for snippet in snippets %} |
579 | + <div> |
580 | + <li>{{ snippet.name }}</li> |
581 | + </div> |
582 | +{% endfor %} |
583 | + |
584 | +<h3>Questions & Answers</h3> |
585 | +{% for question in questions %} |
586 | + <div> |
587 | + <li><a href="{{ question.url }}">{{ question.name }}</a></li> |
588 | + </div> |
589 | +{% endfor %} |
590 | +<h3>Tutorials</h3> |
591 | +{% for tutorial in tutorials %} |
592 | + <div> |
593 | + <li><a href="{{ tutorial.url }}">{{ tutorial.name }}</a></li> |
594 | + </div> |
595 | +{% endfor %} |
596 | +{% endcomment %} |
597 | +{% endblock %} |
598 | |
599 | === modified file 'developer_network/web/templates/web/overview.html' |
600 | --- developer_network/web/templates/web/overview.html 2013-09-13 14:01:30 +0000 |
601 | +++ developer_network/web/templates/web/overview.html 2013-10-31 19:44:44 +0000 |
602 | @@ -3,6 +3,23 @@ |
603 | {% block sub_nav %}{% endblock %} |
604 | |
605 | {% block content %} |
606 | +{% if perms.common %} |
607 | +<section id="editor_actions"> |
608 | + <span style="float: right;"> |
609 | + <ul class="clearfix"> |
610 | + <li><a href="{% url logout %}" title="You are logged in as: {{user.username}}">Logout</a></li> |
611 | + </ul> |
612 | + </span> |
613 | + <span id="editor_links"> |
614 | + <ul class="clearfix"> |
615 | + {% if perms.common.add_topic %} |
616 | + <li><a href="{% url topic_edit %}">+ Topic</a></li> |
617 | + {% endif %} |
618 | + </ul> |
619 | + </span> |
620 | +</section> |
621 | +{% endif %} |
622 | + |
623 | <h2>Topics</h2> |
624 | <ul> |
625 | {% for topic in topics %} |
626 | |
627 | === modified file 'developer_network/web/templates/web/page.html' |
628 | --- developer_network/web/templates/web/page.html 2013-10-04 19:56:27 +0000 |
629 | +++ developer_network/web/templates/web/page.html 2013-10-31 19:44:44 +0000 |
630 | @@ -1,5 +1,14 @@ |
631 | {% extends "web/article.html" %} |
632 | |
633 | +{% block editor_links %} |
634 | + {% if perms.apidocs.change_page %} |
635 | + <li><a href="{% url page_edit topic.slug version.slug page.id %}">Edit</a></li> |
636 | + {% endif %} |
637 | + {% if perms.apidocs.delete_page %} |
638 | + <li><a href="{% url page_edit topic.slug version.slug page.id %}?action=delete">Delete</a></li> |
639 | + {% endif %} |
640 | +{% endblock %} |
641 | + |
642 | {% block breadcrumbs %} |
643 | <li><a class="sub-nav-item" href="{% url topic page.section.topic_version.topic.slug %}">{{page.section.topic_version.topic.name}}</a></li> |
644 | <li> › <a class="sub-nav-item" href="{% url version page.section.topic_version.topic.slug page.section.topic_version.slug %}">{{page.section.topic_version.name}}</a></li> |
645 | |
646 | === added file 'developer_network/web/templates/web/page_edit.html' |
647 | --- developer_network/web/templates/web/page_edit.html 1970-01-01 00:00:00 +0000 |
648 | +++ developer_network/web/templates/web/page_edit.html 2013-10-31 19:44:44 +0000 |
649 | @@ -0,0 +1,25 @@ |
650 | +{% extends "web/article.html" %} |
651 | + |
652 | +{% block editor_links %} |
653 | + {% if page.id and perms.apidocs.delete_page %} |
654 | + <li><a href="{% url page_edit topic.slug version.slug page.id %}?action=delete">Delete</a></li> |
655 | + {% endif %} |
656 | +{% endblock %} |
657 | + |
658 | +{% block breadcrumbs %} |
659 | +{% endblock %} |
660 | + |
661 | +{% block article_content %} |
662 | +{% if page.id %} |
663 | +<h2>Edit {{page.name}}</h2> |
664 | +{% else %} |
665 | +<h2>New Page</h2> |
666 | +{% endif %} |
667 | + |
668 | +<form action="" method="POST" id="page_form"> |
669 | +{% csrf_token %} |
670 | +{{ form.as_p }} |
671 | +<input type="submit" value="Save"> |
672 | +</form> |
673 | + |
674 | +{% endblock %} |
675 | |
676 | === modified file 'developer_network/web/templates/web/release.html' |
677 | --- developer_network/web/templates/web/release.html 2013-09-19 17:48:26 +0000 |
678 | +++ developer_network/web/templates/web/release.html 2013-10-31 19:44:44 +0000 |
679 | @@ -1,5 +1,20 @@ |
680 | {% extends "web/article.html" %} |
681 | |
682 | +{% block editor_links %} |
683 | + {% if perms.common.change_version %} |
684 | + <li><a href="{% url version_edit version.topic.slug version.id %}">Edit</a></li> |
685 | + {% endif %} |
686 | + {% if perms.common.add_section %} |
687 | + <li><a href="{% url section_edit version.topic.slug version.slug %}">+ Section</a></li> |
688 | + {% endif %} |
689 | + {% if perms.apidocs.add_namespace %} |
690 | + <li><a href="{% url namespace_edit version.topic.slug version.slug %}">+ Namespace</a></li> |
691 | + {% endif %} |
692 | + {% if perms.apidocs.add_element %} |
693 | + <li><a href="{% url element_edit version.topic.slug version.slug %}">+ Element</a></li> |
694 | + {% endif %} |
695 | +{% endblock %} |
696 | + |
697 | {% block breadcrumbs %} |
698 | <li><a class="sub-nav-item" href="{% url topic version.topic.slug %}">{{version.topic.name}}</a></li> |
699 | <li> › {{version.name}}</li> |
700 | @@ -10,7 +25,7 @@ |
701 | <table class="section_list"><tr> |
702 | <td id="first_column"> |
703 | {% for section in first_column %} |
704 | - <h3>{{section.name}}</h3> |
705 | + <h3 class="section_title">{{section.name}}{% if perms.common.change_section %}<a class="section_editor_action" href="{% url section_edit version.topic.slug version.slug section.id %}">Edit</a>{% endif %}</h3> |
706 | <ul> |
707 | {% for namespace in section.namespace_set.all %} |
708 | <li><a href="{% url element version.topic.slug version.slug namespace.name %}">{{namespace.name}}</a></li> |
709 | @@ -33,7 +48,7 @@ |
710 | {% if second_column %} |
711 | <td id="second_column"> |
712 | {% for section in second_column %} |
713 | - <h3>{{section.name}}</h3> |
714 | + <h3 class="section_title">{{section.name}}{% if perms.common.change_section %}<a class="section_editor_action" href="{% url section_edit version.topic.slug version.slug section.id %}">Edit</a>{% endif %}</h3> |
715 | <ul> |
716 | {% for namespace in section.namespace_set.all %} |
717 | <li><a href="{% url element version.topic.slug version.slug namespace.name %}">{{namespace.name}}</a></li> |
718 | |
719 | === modified file 'developer_network/web/templates/web/search.html' |
720 | --- developer_network/web/templates/web/search.html 2013-09-23 21:27:54 +0000 |
721 | +++ developer_network/web/templates/web/search.html 2013-10-31 19:44:44 +0000 |
722 | @@ -1,5 +1,7 @@ |
723 | {% extends "web/article.html" %} |
724 | |
725 | +{% block editor_actions %}{% endblock %} |
726 | + |
727 | {% block breadcrumbs %} |
728 | <li><a class="sub-nav-item" href="{% url topic version.topic.slug %}">{{version.topic.name}}</a></li> |
729 | <li> › <a class="sub-nav-item" href="{% url version version.topic.slug version.slug %}">{{version.name}}</a></li> |
730 | |
731 | === added file 'developer_network/web/templates/web/section_edit.html' |
732 | --- developer_network/web/templates/web/section_edit.html 1970-01-01 00:00:00 +0000 |
733 | +++ developer_network/web/templates/web/section_edit.html 2013-10-31 19:44:44 +0000 |
734 | @@ -0,0 +1,25 @@ |
735 | +{% extends "web/article.html" %} |
736 | + |
737 | +{% block editor_links %} |
738 | + {% if section.id and perms.common.delete_section %} |
739 | + <li><a href="{% url section_edit topic.slug version.slug section.id %}?action=delete">Delete</a></li> |
740 | + {% endif %} |
741 | +{% endblock %} |
742 | + |
743 | +{% block breadcrumbs %} |
744 | +{% endblock %} |
745 | + |
746 | +{% block article_content %} |
747 | +{% if section.id %} |
748 | +<h2>Edit {{section.name}}</h2> |
749 | +{% else %} |
750 | +<h2>New Section</h2> |
751 | +{% endif %} |
752 | + |
753 | +<form action="" method="POST" id="section_form"> |
754 | +{% csrf_token %} |
755 | +{{ form.as_p }} |
756 | +<input type="submit" value="Save"> |
757 | +</form> |
758 | + |
759 | +{% endblock %} |
760 | |
761 | === added file 'developer_network/web/templates/web/topic_edit.html' |
762 | --- developer_network/web/templates/web/topic_edit.html 1970-01-01 00:00:00 +0000 |
763 | +++ developer_network/web/templates/web/topic_edit.html 2013-10-31 19:44:44 +0000 |
764 | @@ -0,0 +1,18 @@ |
765 | +{% extends "web/base.html" %} |
766 | + |
767 | +{% block sub_nav %}{% endblock %} |
768 | + |
769 | +{% block content %} |
770 | + |
771 | +{% if topic.id %} |
772 | +<h2>Edit: {{topic.name}}</h2> |
773 | +{% else %} |
774 | +<h2>New Topic</h2> |
775 | +{% endif %} |
776 | + |
777 | +<form action="" method="POST" id="topic_form"> |
778 | +{% csrf_token %} |
779 | +{{ form.as_p }} |
780 | +<input type="submit" value="Save"> |
781 | +</form> |
782 | +{% endblock %} |
783 | |
784 | === added file 'developer_network/web/templates/web/version_edit.html' |
785 | --- developer_network/web/templates/web/version_edit.html 1970-01-01 00:00:00 +0000 |
786 | +++ developer_network/web/templates/web/version_edit.html 2013-10-31 19:44:44 +0000 |
787 | @@ -0,0 +1,23 @@ |
788 | +{% extends "web/base.html" %} |
789 | + |
790 | +{% block editor_links %} |
791 | + <li><a href="{% url version_edit version.id %}?action=delete">Delete</a></li> |
792 | +{% endblock %} |
793 | + |
794 | +{% block breadcrumbs %} |
795 | +{% endblock %} |
796 | + |
797 | +{% block content %} |
798 | +{% if version.id %} |
799 | +<h2>Edit {{version.name}}</h2> |
800 | +{% else %} |
801 | +<h2>New Version</h2> |
802 | +{% endif %} |
803 | + |
804 | +<form action="" method="POST" id="element_form"> |
805 | +{% csrf_token %} |
806 | +{{ form.as_p }} |
807 | +<input type="submit" value="Save"> |
808 | +</form> |
809 | + |
810 | +{% endblock %} |
811 | |
812 | === modified file 'developer_network/web/views.py' |
813 | --- developer_network/web/views.py 2013-10-04 19:56:27 +0000 |
814 | +++ developer_network/web/views.py 2013-10-31 19:44:44 +0000 |
815 | @@ -2,6 +2,7 @@ |
816 | from django.http import HttpResponse, HttpResponseRedirect |
817 | from django.core.urlresolvers import reverse |
818 | from django.template import loader, RequestContext |
819 | +from django.forms import ModelForm |
820 | |
821 | from common.models import Topic, Version, Section |
822 | from apidocs.models import Namespace, Element, Page |
823 | @@ -24,6 +25,32 @@ |
824 | } |
825 | return render_to_response('web/distro.html', context, RequestContext(request)) |
826 | |
827 | +class TopicForm(ModelForm): |
828 | + class Meta: |
829 | + model = Topic |
830 | + |
831 | +def topic_edit(request, topic_id=0): |
832 | + if topic_id: |
833 | + topic = get_object_or_404(Topic, id=topic_id) |
834 | + else: |
835 | + topic = Topic() |
836 | + |
837 | + if not request.user.has_perm('common.change_topic'): |
838 | + return HttpResponseRedirect(reverse(topic_view, args=[topic.slug])) |
839 | + |
840 | + if request.method == 'POST': |
841 | + form = TopicForm(request.POST, instance=topic) |
842 | + if form.is_valid(): |
843 | + form.save() |
844 | + return HttpResponseRedirect(reverse(topic_view, args=[topic.slug])) |
845 | + else: |
846 | + form = TopicForm(instance=topic) |
847 | + context = { |
848 | + 'form': form, |
849 | + 'topic': topic, |
850 | + } |
851 | + return render_to_response('web/topic_edit.html', context, RequestContext(request)) |
852 | + |
853 | def version_view(request, topic_name, release_version): |
854 | version = get_object_or_404(Version, topic__slug=topic_name, slug=release_version) |
855 | |
856 | @@ -63,6 +90,68 @@ |
857 | } |
858 | return render_to_response('web/release.html', context, RequestContext(request)) |
859 | |
860 | +class VersionForm(ModelForm): |
861 | + class Meta: |
862 | + model = Version |
863 | + |
864 | +def version_edit(request, topic_name, version_id=0): |
865 | + if version_id: |
866 | + version = get_object_or_404(Version, topic__slug=topic_name, id=version_id) |
867 | + topic = version.topic |
868 | + else: |
869 | + topic = get_object_or_404(Topic, slug=topic_name) |
870 | + version = Version(topic=topic) |
871 | + |
872 | + if not request.user.has_perm('common.change_version'): |
873 | + return HttpResponseRedirect(reverse(version_view, args=[topic.slug, version.slug])) |
874 | + |
875 | + if request.method == 'POST': |
876 | + form = VersionForm(request.POST, instance=version) |
877 | + if form.is_valid(): |
878 | + form.save() |
879 | + return HttpResponseRedirect(reverse(version_view, args=[topic.slug, version.slug])) |
880 | + else: |
881 | + form = VersionForm(instance=version) |
882 | + context = { |
883 | + 'form': form, |
884 | + 'topic': topic, |
885 | + 'version': version, |
886 | + } |
887 | + return render_to_response('web/version_edit.html', context, RequestContext(request)) |
888 | + |
889 | +class SectionForm(ModelForm): |
890 | + class Meta: |
891 | + model = Section |
892 | + |
893 | +def section_edit(request, topic_name, version_name, section_id=0): |
894 | + if section_id: |
895 | + section = get_object_or_404(Section, topic_version__topic__slug=topic_name, topic_version__slug=version_name, id=section_id) |
896 | + version = section.topic_version |
897 | + topic = version.topic |
898 | + else: |
899 | + topic = get_object_or_404(Topic, slug=topic_name) |
900 | + version = get_object_or_404(Version, topic=topic, slug=version_name) |
901 | + section = Section(topic_version=version) |
902 | + |
903 | + if not request.user.has_perm('common.change_section'): |
904 | + return HttpResponseRedirect(reverse(version_view, args=[topic.slug, version.slug])) |
905 | + |
906 | + if request.method == 'POST': |
907 | + form = SectionForm(request.POST, instance=section) |
908 | + if form.is_valid(): |
909 | + form.save() |
910 | + return HttpResponseRedirect(reverse(version_view, args=[topic.slug, version.slug])) |
911 | + else: |
912 | + form = SectionForm(instance=section) |
913 | + context = { |
914 | + 'sidenav': topic_name, |
915 | + 'form': form, |
916 | + 'topic': topic, |
917 | + 'version': version, |
918 | + 'section': section, |
919 | + } |
920 | + return render_to_response('web/section_edit.html', context, RequestContext(request)) |
921 | + |
922 | def namespace_view(request, topic_name, release_version, namespace_name): |
923 | try: |
924 | namespace = Namespace.objects.get(platform_section__topic_version__slug=release_version, platform_section__topic_version__topic__slug=topic_name, name=namespace_name) |
925 | @@ -82,6 +171,50 @@ |
926 | } |
927 | return render_to_response('web/namespace.html', context, RequestContext(request)) |
928 | |
929 | +class NamespaceForm(ModelForm): |
930 | + class Meta: |
931 | + model = Namespace |
932 | + |
933 | + def __init__(self, *args, **kargs): |
934 | + if 'version' in kargs: |
935 | + version = kargs['version'] |
936 | + del kargs['version'] |
937 | + elif hasattr(self, 'instance') and self.instance.section: |
938 | + version = self.instance.section.topic_version |
939 | + else: |
940 | + version=None |
941 | + super(NamespaceForm, self).__init__(*args, **kargs) |
942 | + self.fields['platform_section'].queryset = Section.objects.filter(topic_version=version) |
943 | + |
944 | +def namespace_edit(request, topic_name, version_name, namespace_id=0): |
945 | + if namespace_id: |
946 | + namespace = get_object_or_404(Namespace, platform_section__topic_version__slug=version_name, platform_section__topic_version__topic__slug=topic_name, id=namespace_id) |
947 | + version = namespace.platform_section.topic_version |
948 | + topic = version.topic |
949 | + else: |
950 | + topic = get_object_or_404(Topic, slug=topic_name) |
951 | + version = get_object_or_404(Version, slug=version_name, topic=topic) |
952 | + namespace = Namespace() |
953 | + |
954 | + if not request.user.has_perm('apidocs.change_namespace'): |
955 | + return HttpResponseRedirect(reverse(element_view, args=[topic_name, version_name, namespace.name])) |
956 | + |
957 | + if request.method == 'POST': |
958 | + form = NamespaceForm(request.POST, instance=namespace, version=version) |
959 | + if form.is_valid(): |
960 | + form.save() |
961 | + return HttpResponseRedirect(reverse(element_view, args=[topic_name, version_name, namespace.name])) |
962 | + else: |
963 | + form = NamespaceForm(instance=namespace, version=version) |
964 | + context = { |
965 | + 'form': form, |
966 | + 'sidenav': topic_name, |
967 | + 'topic': topic, |
968 | + 'version': version, |
969 | + 'namespace': namespace, |
970 | + } |
971 | + return render_to_response('web/namespace_edit.html', context, RequestContext(request)) |
972 | + |
973 | def page_view(request, topic_name, release_version, page_fullname): |
974 | page = get_object_or_404(Page, section__topic_version__slug=release_version, section__topic_version__topic__slug=topic_name, fullname=page_fullname) |
975 | |
976 | @@ -99,6 +232,51 @@ |
977 | } |
978 | return render_to_response('web/page.html', context, RequestContext(request)) |
979 | |
980 | +class PageForm(ModelForm): |
981 | + class Meta: |
982 | + model = Page |
983 | + |
984 | + def __init__(self, *args, **kargs): |
985 | + if 'version' in kargs: |
986 | + version = kargs['version'] |
987 | + del kargs['version'] |
988 | + elif hasattr(self, 'instance') and self.instance.section: |
989 | + version = self.instance.section.topic_version |
990 | + else: |
991 | + version=None |
992 | + super(PageForm, self).__init__(*args, **kargs) |
993 | + self.fields['section'].queryset = Section.objects.filter(topic_version=version) |
994 | + self.fields['namespace'].queryset = Namespace.objects.filter(platform_section__topic_version=version) |
995 | + |
996 | +def page_edit(request, topic_name, release_version, page_id=0): |
997 | + if page_id: |
998 | + page = get_object_or_404(Page, section__topic_version__slug=release_version, section__topic_version__topic__slug=topic_name, id=page_id) |
999 | + version = page.section.topic_version |
1000 | + topic = version.topic |
1001 | + else: |
1002 | + topic = get_object_or_404(Topic, slug=topic_name) |
1003 | + version = get_object_or_404(Version, slug=release_version, topic=topic) |
1004 | + page = Page() |
1005 | + |
1006 | + if not request.user.has_perm('apidocs.change_page'): |
1007 | + return HttpResponseRedirect(reverse(version_view, args=[topic_name, release_version])) |
1008 | + |
1009 | + if request.method == 'POST': |
1010 | + form = PageForm(request.POST, instance=page, version=version) |
1011 | + if form.is_valid(): |
1012 | + form.save() |
1013 | + return HttpResponseRedirect(reverse(version_view, args=[topic_name, release_version])) |
1014 | + else: |
1015 | + form = PageForm(instance=page, version=version) |
1016 | + context = { |
1017 | + 'form': form, |
1018 | + 'sidenav': topic_name, |
1019 | + 'topic': topic, |
1020 | + 'version': version, |
1021 | + 'page': page, |
1022 | + } |
1023 | + return render_to_response('web/page_edit.html', context, RequestContext(request)) |
1024 | + |
1025 | def element_view(request, topic_name, release_version, element_fullname): |
1026 | try: |
1027 | element = Element.objects.get(section__topic_version__slug=release_version, section__topic_version__topic__slug=topic_name, fullname=element_fullname) |
1028 | @@ -120,6 +298,51 @@ |
1029 | 'tutorials': tutorials |
1030 | } |
1031 | return render_to_response('web/element.html', context, RequestContext(request)) |
1032 | + |
1033 | +class ElementForm(ModelForm): |
1034 | + class Meta: |
1035 | + model = Element |
1036 | + |
1037 | + def __init__(self, *args, **kargs): |
1038 | + if 'version' in kargs: |
1039 | + version = kargs['version'] |
1040 | + del kargs['version'] |
1041 | + elif hasattr(self, 'instance') and self.instance.section: |
1042 | + version = self.instance.section.topic_version |
1043 | + else: |
1044 | + version=None |
1045 | + super(ElementForm, self).__init__(*args, **kargs) |
1046 | + self.fields['section'].queryset = Section.objects.filter(topic_version=version) |
1047 | + self.fields['namespace'].queryset = Namespace.objects.filter(platform_section__topic_version=version) |
1048 | + |
1049 | +def element_edit(request, topic_name, release_version, element_id=0): |
1050 | + if element_id: |
1051 | + element = get_object_or_404(Element, section__topic_version__slug=release_version, section__topic_version__topic__slug=topic_name, id=element_id) |
1052 | + version = element.section.topic_version |
1053 | + topic = version.topic |
1054 | + else: |
1055 | + topic = get_object_or_404(Topic, slug=topic_name) |
1056 | + version = get_object_or_404(Version, slug=release_version, topic=topic) |
1057 | + element = Element() |
1058 | + |
1059 | + if not request.user.has_perm('apidocs.change_element'): |
1060 | + return HttpResponseRedirect(reverse(element_view, args=[topic_name, release_version, element.fullname])) |
1061 | + |
1062 | + if request.method == 'POST': |
1063 | + form = ElementForm(request.POST, instance=element, version=version) |
1064 | + if form.is_valid(): |
1065 | + form.save() |
1066 | + return HttpResponseRedirect(reverse(element_view, args=[topic_name, release_version, element.fullname])) |
1067 | + else: |
1068 | + form = ElementForm(instance=element, version=version) |
1069 | + context = { |
1070 | + 'form': form, |
1071 | + 'sidenav': topic_name, |
1072 | + 'topic': topic, |
1073 | + 'version': version, |
1074 | + 'element': element, |
1075 | + } |
1076 | + return render_to_response('web/element_edit.html', context, RequestContext(request)) |
1077 | |
1078 | def search(request, topic_name, release_version): |
1079 | version = get_object_or_404(Version, topic__slug=topic_name, slug=release_version) |
1080 | |
1081 | === modified file 'requirements.txt' |
1082 | --- requirements.txt 2013-09-11 16:48:02 +0000 |
1083 | +++ requirements.txt 2013-10-31 19:44:44 +0000 |
1084 | @@ -3,3 +3,5 @@ |
1085 | distribute==0.6.31 |
1086 | wsgiref==0.1.2 |
1087 | South==0.8.2 |
1088 | +django-openid-auth==0.5 |
1089 | +python-openid==2.2.4 |
Confirmed locally and in LXC deployment