Added a basic front-end for adding subprojects.
parent
5d670a97eb
commit
d21e880da2
|
@ -216,3 +216,23 @@ def build_upload_html_form(project):
|
|||
choices=choices,
|
||||
)
|
||||
return type('UploadHTMLForm', (BaseUploadHTMLForm,), attrs)
|
||||
|
||||
|
||||
class SubprojectForm(forms.Form):
|
||||
subproject = forms.CharField()
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.parent = kwargs.pop('parent', None)
|
||||
super(SubprojectForm, self).__init__(*args, **kwargs)
|
||||
|
||||
def clean_subproject(self):
|
||||
subproject_name = self.cleaned_data['subproject']
|
||||
subproject_qs = Project.objects.filter(name=subproject_name)
|
||||
if not subproject_qs.exists():
|
||||
raise forms.ValidationError("Project %s does not exist" % subproject_name)
|
||||
self.subproject = subproject_qs[0]
|
||||
return subproject_name
|
||||
|
||||
def save(self):
|
||||
relationship = self.parent.add_subproject(self.subproject)
|
||||
return relationship
|
||||
|
|
|
@ -31,6 +31,10 @@ class ProjectRelationship(models.Model):
|
|||
def __unicode__(self):
|
||||
return "%s -> %s" % (self.parent, self.child)
|
||||
|
||||
#HACK
|
||||
def get_absolute_url(self):
|
||||
return "http://%s.readthedocs.org/docs/%s/en/latest/" % (self.parent.slug, self.child.slug)
|
||||
|
||||
class Project(models.Model):
|
||||
#Auto fields
|
||||
pub_date = models.DateTimeField(auto_now_add=True)
|
||||
|
@ -377,6 +381,19 @@ class Project(models.Model):
|
|||
return self.default_version
|
||||
return 'latest'
|
||||
|
||||
def add_subproject(self, child):
|
||||
subproject, created = ProjectRelationship.objects.get_or_create(
|
||||
parent=self,
|
||||
child=child,
|
||||
)
|
||||
return subproject
|
||||
|
||||
def remove_subproject(self, child):
|
||||
ProjectRelationship.objects.filter(
|
||||
parent=self,
|
||||
child=child).delete()
|
||||
return
|
||||
|
||||
|
||||
class FileManager(models.Manager):
|
||||
def live(self, *args, **kwargs):
|
||||
|
|
|
@ -49,6 +49,10 @@ urlpatterns = patterns('projects.views.private',
|
|||
'project_delete',
|
||||
name='projects_delete'
|
||||
),
|
||||
url(r'^(?P<project_slug>[-\w]+)/subprojects/$',
|
||||
'project_subprojects',
|
||||
name='projects_subprojects'
|
||||
),
|
||||
url(r'^(?P<project_slug>[-\w]+)/add/$',
|
||||
'file_add',
|
||||
name='projects_file_add'
|
||||
|
|
|
@ -18,7 +18,8 @@ from builds.forms import AliasForm
|
|||
from projects import constants
|
||||
from projects.forms import (FileForm, CreateProjectForm,
|
||||
ImportProjectForm, FileRevisionForm,
|
||||
build_versions_form, build_upload_html_form)
|
||||
build_versions_form, build_upload_html_form,
|
||||
SubprojectForm)
|
||||
from projects.models import Project, File
|
||||
from projects.tasks import unzip_files
|
||||
|
||||
|
@ -363,10 +364,6 @@ def upload_html(request, project_slug):
|
|||
|
||||
@login_required
|
||||
def edit_alias(request, project_slug, id=None):
|
||||
"""
|
||||
The view for creating a new project where the docs will be hosted
|
||||
as objects and edited through the site
|
||||
"""
|
||||
proj = get_object_or_404(Project.objects.all(), slug=project_slug)
|
||||
if id:
|
||||
alias = proj.aliases.get(pk=id)
|
||||
|
@ -385,10 +382,6 @@ def edit_alias(request, project_slug, id=None):
|
|||
|
||||
@login_required
|
||||
def list_alias(request, project_slug):
|
||||
"""
|
||||
The view for creating a new project where the docs will be hosted
|
||||
as objects and edited through the site
|
||||
"""
|
||||
proj = get_object_or_404(Project.objects.all(), slug=project_slug)
|
||||
return object_list(
|
||||
request,
|
||||
|
@ -396,3 +389,25 @@ def list_alias(request, project_slug):
|
|||
template_object_name='alias',
|
||||
template_name='projects/alias_list.html',
|
||||
)
|
||||
|
||||
@login_required
|
||||
def project_subprojects(request, project_slug):
|
||||
project = get_object_or_404(request.user.projects.live(), slug=project_slug)
|
||||
|
||||
if not project.is_imported:
|
||||
raise Http404
|
||||
|
||||
form = SubprojectForm(data=request.POST or None, parent=project)
|
||||
|
||||
if request.method == 'POST' and form.is_valid():
|
||||
form.save()
|
||||
project_dashboard = reverse('projects_manage', args=[project.slug])
|
||||
return HttpResponseRedirect(project_dashboard)
|
||||
|
||||
subprojects = project.subprojects.all()
|
||||
|
||||
return render_to_response(
|
||||
'projects/project_subprojects.html',
|
||||
{'form': form, 'project': project, 'subprojects': subprojects},
|
||||
context_instance=RequestContext(request)
|
||||
)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<html lang="en">
|
||||
|
||||
<head>
|
||||
|
||||
|
||||
<!-- meta -->
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="icon" type="image/png" href="{{ MEDIA_URL }}images/favicon.png">
|
||||
|
@ -15,7 +15,7 @@
|
|||
{% block extra_links %}{% endblock %}
|
||||
|
||||
<!-- js -->
|
||||
|
||||
|
||||
<!-- jquery -->
|
||||
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.4/jquery-ui.min.js"></script>
|
||||
|
@ -23,7 +23,7 @@
|
|||
<!-- typekit -->
|
||||
<script type="text/javascript" src="http://use.typekit.com/xgl8ypn.js"></script>
|
||||
<script type="text/javascript">try{Typekit.load();}catch(e){}</script>
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript" src="{{ MEDIA_URL }}javascript/rtd.js"></script>
|
||||
|
||||
|
@ -63,13 +63,13 @@
|
|||
<!-- BEGIN footer-->
|
||||
<div id="footer">
|
||||
<div class="wrapper">
|
||||
|
||||
|
||||
<hr>
|
||||
|
||||
{% block footer-content %}
|
||||
<p>2010. Created by <a href="http://ericholscher.com/">Eric Holscher</a>, <a href="http://charlesleifer.com/">Charles Leifer</a>, and <a href="http://bobbygrace.info/">Bobby Grace</a> for the 2010 <a href="http://djangodash.com/">Django Dash</a>.
|
||||
<p>2010. Created by <a href="http://ericholscher.com/">Eric Holscher</a>, <a href="http://charlesleifer.com/">Charles Leifer</a>, and <a href="http://bobbygrace.info/">Bobby Grace</a> for the 2010 <a href="http://djangodash.com/">Django Dash</a>.
|
||||
|
||||
<a href="http://github.com/rtfd/readthedocs.org">Github</a> | <a href="http://read-the-docs.readthedocs.org">Docs</a>. Sponsored by <a href="http://revsys.com">RevSys</a>, <a href="http://www.python.org/psf/">The Python Software Foundation</a>, and <a href="http://blog.mozilla.com/webdev/">Mozilla Web Dev</a>.</p>
|
||||
<a href="http://github.com/rtfd/readthedocs.org">Github</a> | <a href="http://read-the-docs.readthedocs.org">Docs</a>. Sponsored by <a href="http://revsys.com">RevSys</a>, <a href="http://www.python.org/psf/">The Python Software Foundation</a>, and <a href="http://blog.mozilla.com/webdev/">Mozilla Web Dev</a>.</p>
|
||||
{% endblock %}
|
||||
|
||||
</div>
|
||||
|
@ -94,12 +94,14 @@
|
|||
$('.rtfd-header-search input:text').autocomplete({
|
||||
source: '{% url search_autocomplete %}',
|
||||
minLength: 2,
|
||||
open: function(event, ui) {
|
||||
ac_top = $('.ui-autocomplete').css('top');
|
||||
$('.ui-autocomplete').css({'width': '233px', 'top': ac_top + 10 });
|
||||
open: function(event, ui) {
|
||||
ac_top = $('.ui-autocomplete').css('top');
|
||||
$('.ui-autocomplete').css({'width': '233px', 'top': ac_top + 10 });
|
||||
}
|
||||
});
|
||||
|
||||
{% block footerjs %}{% endblock %}
|
||||
|
||||
</script>
|
||||
<!-- END google analytics -->
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
<li {% block editing-option-manage %}{% endblock %}><a href="{% url projects_manage project.slug %}">Manage Files</a></li>
|
||||
{% endif %}
|
||||
<li {% block editing-option-edit-proj %}{% endblock %}><a href="{% url projects_edit project.slug %}">Edit Project</a></li>
|
||||
<li><a href="{% url projects_subprojects project.slug %}">Subprojects</a></li>
|
||||
{% endif %}
|
||||
|
||||
{% if project.get_latest_build %}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
<!-- <input type="submit" value="Go"> -->
|
||||
</form>
|
||||
</div>
|
||||
<br>
|
||||
<!-- BEGIN search bar -->
|
||||
|
||||
|
||||
|
@ -59,20 +60,17 @@
|
|||
<p> This project has more information available about it on <a href="{{ project.django_packages_url }}">Django Packages!</a></p>
|
||||
{% endif %}
|
||||
|
||||
{% comment %}
|
||||
{% if project.subprojects.count %}
|
||||
{% if project.subprojects.exists %}
|
||||
<h3>Sub Projects</h3>
|
||||
<p>
|
||||
{% for project in project.subprojects.all %}
|
||||
<li><a href="{{ project.get_docs_url }}">{{ project.child }}</a></li>
|
||||
{% for rel in project.subprojects.all %}
|
||||
<li><a href="{{ rel.get_absolute_url }}">{{ rel.child }}</a></li>
|
||||
{% empty %}
|
||||
<span class="quiet">No tags</span>
|
||||
{% endfor %}
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
{% endcomment %}
|
||||
|
||||
|
||||
<h3>Last Built</h3>
|
||||
<p>{{ project.modified_date|timesince }} ago</p>
|
||||
|
|
|
@ -34,6 +34,11 @@
|
|||
{% if project.has_aliases %}
|
||||
<li><a href="{% url projects_alias_list project.slug %}" rel="nofollow,noindex">Aliases</a></li>
|
||||
{% endif %}
|
||||
|
||||
{% comment %}
|
||||
<li><a href="{% url projects_subprojects project.slug %}">Subprojects</a></li>
|
||||
{% endcomment %}
|
||||
|
||||
<li><a href="{% url projects_edit project.slug %}">Edit</a></li>
|
||||
<li><a href="{{ project.get_docs_url }}">View Docs</a></li>
|
||||
</ul>
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
{% extends "projects/base_project_editing.html" %}
|
||||
|
||||
{% block title %}Edit Subprojects{% endblock %}
|
||||
|
||||
{% block editing-option-edit-proj %}class="active"{% endblock %}
|
||||
|
||||
{% block content-header %}<h1>Edit Subprojects</h1>{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<p class="help_text">
|
||||
This allows you to add subprojects to your project. This allows them to live in the same namespace in the URLConf for a subdomain or CNAME.
|
||||
</p>
|
||||
|
||||
<h3> Existing Subprojects </h3>
|
||||
<p>
|
||||
<ul>
|
||||
{% for relationship in subprojects %}
|
||||
<li>
|
||||
<a href="{{ relationship.get_absolute_url }}">
|
||||
{{ relationship.child }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<p>
|
||||
Choose which project you would like to add as a subproject.
|
||||
</p>
|
||||
<form method="post" action=".">{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<p>
|
||||
<input style="display: inline;" type="submit" value="Submit">
|
||||
</p>
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block footerjs %}
|
||||
$('#id_subproject').autocomplete({
|
||||
source: '{% url search_autocomplete %}',
|
||||
minLength: 2,
|
||||
open: function(event, ui) {
|
||||
ac_top = $('.ui-autocomplete').css('top');
|
||||
$('.ui-autocomplete').css({'width': '233px', 'top': ac_top + 10 });
|
||||
}
|
||||
});
|
||||
|
||||
{% endblock %}
|
Loading…
Reference in New Issue