Browse Source

Redesigned and bugfixed split/move moderation actions

Ralfp 12 years ago
parent
commit
042465de41

+ 15 - 0
misago/forms/__init__.py

@@ -1,5 +1,7 @@
 from django import forms
 from django import forms
+from django.utils.html import conditional_escape, mark_safe
 from django.utils.translation import ugettext_lazy as _
 from django.utils.translation import ugettext_lazy as _
+from mptt.forms import TreeNodeChoiceField
 from misago.forms.layouts import *
 from misago.forms.layouts import *
 from recaptcha.client.captcha import submit as recaptcha_submit
 from recaptcha.client.captcha import submit as recaptcha_submit
 
 
@@ -159,3 +161,16 @@ class YesNoSwitch(forms.CheckboxInput):
     Custom Yes-No switch as fancier alternative to checkboxes
     Custom Yes-No switch as fancier alternative to checkboxes
     """
     """
     pass
     pass
+
+
+class ForumChoiceField(TreeNodeChoiceField):
+    """
+    Custom forum choice field
+    """
+    def __init__(self, *args, **kwargs):
+        kwargs['level_indicator'] = u'- - '
+        super(ForumChoiceField, self).__init__(*args, **kwargs)
+
+    def _get_level_indicator(self, obj):
+        level = getattr(obj, obj._mptt_meta.level_attr)
+        return mark_safe(conditional_escape(self.level_indicator) * (level - 1))

+ 15 - 7
misago/threads/forms.py

@@ -1,9 +1,8 @@
 from django import forms
 from django import forms
 from django.conf import settings
 from django.conf import settings
 from django.utils.translation import ungettext, ugettext_lazy as _
 from django.utils.translation import ungettext, ugettext_lazy as _
-from mptt.forms import TreeNodeChoiceField
 from misago.acl.utils import ACLError403, ACLError404
 from misago.acl.utils import ACLError403, ACLError404
-from misago.forms import Form
+from misago.forms import Form, ForumChoiceField
 from misago.forums.models import Forum
 from misago.forums.models import Forum
 from misago.threads.models import Thread
 from misago.threads.models import Thread
 from misago.utils import slugify
 from misago.utils import slugify
@@ -92,7 +91,7 @@ class SplitThreadForm(Form, ThreadNameMixin):
                                                                                     _("Thread name must contain at least one alpha-numeric character."),
                                                                                     _("Thread name must contain at least one alpha-numeric character."),
                                                                                     _("Thread name is too long. Try shorter name.")
                                                                                     _("Thread name is too long. Try shorter name.")
                                                                                     )])
                                                                                     )])
-        self.fields['thread_forum'] = TreeNodeChoiceField(queryset=Forum.tree.get(token='root').get_descendants().filter(pk__in=self.request.acl.forums.acl['can_browse']), level_indicator=u'- - ')
+        self.fields['thread_forum'] = ForumChoiceField(queryset=Forum.tree.get(token='root').get_descendants().filter(pk__in=self.request.acl.forums.acl['can_browse']))
 
 
     def clean_thread_forum(self):
     def clean_thread_forum(self):
         new_forum = self.cleaned_data['thread_forum']
         new_forum = self.cleaned_data['thread_forum']
@@ -151,12 +150,12 @@ class MoveThreadsForm(Form):
         super(MoveThreadsForm, self).__init__(data, request=request, *args, **kwargs)
         super(MoveThreadsForm, self).__init__(data, request=request, *args, **kwargs)
 
 
     def finalize_form(self):
     def finalize_form(self):
-        self.fields['new_forum'] = TreeNodeChoiceField(queryset=Forum.tree.get(token='root').get_descendants().filter(pk__in=self.request.acl.forums.acl['can_browse']), level_indicator=u'- - ')
+        self.fields['new_forum'] = ForumChoiceField(queryset=Forum.tree.get(token='root').get_descendants().filter(pk__in=self.request.acl.forums.acl['can_browse']))
         self.layout = [
         self.layout = [
                        [
                        [
-                        _("Thread Options"),
+                        None,
                         [
                         [
-                         ('new_forum', {'label': _("Move Thread to"), 'help_text': _("Select forum you want to move threads to.")}),
+                         ('new_forum', {'label': _("Move Threads to"), 'help_text': _("Select forum you want to move threads to.")}),
                          ],
                          ],
                         ],
                         ],
                        ]
                        ]
@@ -177,6 +176,7 @@ class MergeThreadsForm(Form, ThreadNameMixin):
         super(MergeThreadsForm, self).__init__(data, request=request, *args, **kwargs)
         super(MergeThreadsForm, self).__init__(data, request=request, *args, **kwargs)
 
 
     def finalize_form(self):
     def finalize_form(self):
+        self.fields['new_forum'] = ForumChoiceField(queryset=Forum.tree.get(token='root').get_descendants().filter(pk__in=self.request.acl.forums.acl['can_browse']), initial=self.threads[0].forum)
         self.fields['thread_name'] = forms.CharField(
         self.fields['thread_name'] = forms.CharField(
                                                      max_length=self.request.settings['thread_name_max'],
                                                      max_length=self.request.settings['thread_name_max'],
                                                      initial=self.threads[0].name,
                                                      initial=self.threads[0].name,
@@ -186,9 +186,10 @@ class MergeThreadsForm(Form, ThreadNameMixin):
                                                                                     )])
                                                                                     )])
         self.layout = [
         self.layout = [
                        [
                        [
-                        _("Thread Options"),
+                        None,
                         [
                         [
                          ('thread_name', {'label': _("Thread Name"), 'help_text': _("Name of new thread that will be created as result of merge.")}),
                          ('thread_name', {'label': _("Thread Name"), 'help_text': _("Name of new thread that will be created as result of merge.")}),
+                         ('new_forum', {'label': _("Thread Forum"), 'help_text': _("Select forum you want to put new thread in.")}),
                          ],
                          ],
                         ],
                         ],
                        [
                        [
@@ -205,6 +206,13 @@ class MergeThreadsForm(Form, ThreadNameMixin):
             self.fields['thread_%s' % thread.pk] = forms.ChoiceField(choices=choices, initial=str(i))
             self.fields['thread_%s' % thread.pk] = forms.ChoiceField(choices=choices, initial=str(i))
             self.layout[1][1].append(('thread_%s' % thread.pk, {'label': thread.name}))
             self.layout[1][1].append(('thread_%s' % thread.pk, {'label': thread.name}))
 
 
+    def clean_new_forum(self):
+        new_forum = self.cleaned_data['new_forum']
+        # Assert its forum
+        if new_forum.type != 'forum':
+            raise forms.ValidationError(_("This is not forum."))
+        return new_forum
+
     def clean(self):
     def clean(self):
         cleaned_data = super(MergeThreadsForm, self).clean()
         cleaned_data = super(MergeThreadsForm, self).clean()
         self.merge_order = {}
         self.merge_order = {}

+ 4 - 4
misago/threads/models.py

@@ -314,10 +314,10 @@ move_forum_content.connect(move_forum_content_handler, dispatch_uid="move_forum_
 
 
 
 
 def move_thread_handler(sender, **kwargs):
 def move_thread_handler(sender, **kwargs):
-    Post.objects.filter(forum=sender.forum_pk).update(forum=kwargs['move_to'])
-    Karma.objects.filter(forum=sender.forum_pk).update(forum=kwargs['move_to'])
-    Change.objects.filter(forum=sender.forum_pk).update(forum=kwargs['move_to'])
-    Checkpoint.objects.filter(forum=sender.forum_pk).update(forum=kwargs['move_to'])
+    Post.objects.filter(forum=sender.forum_id).update(forum=kwargs['move_to'])
+    Karma.objects.filter(forum=sender.forum_id).update(forum=kwargs['move_to'])
+    Change.objects.filter(forum=sender.forum_id).update(forum=kwargs['move_to'])
+    Checkpoint.objects.filter(forum=sender.forum_id).update(forum=kwargs['move_to'])
 
 
 move_thread.connect(move_thread_handler, dispatch_uid="move_thread")
 move_thread.connect(move_thread_handler, dispatch_uid="move_thread")
 
 

+ 5 - 2
misago/threads/views/list.py

@@ -217,7 +217,7 @@ class ThreadsView(BaseView):
             self.message = Message(form.non_field_errors()[0], 'error')
             self.message = Message(form.non_field_errors()[0], 'error')
         else:
         else:
             form = MoveThreadsForm(request=self.request, forum=self.forum)
             form = MoveThreadsForm(request=self.request, forum=self.forum)
-        return self.request.theme.render_to_response('threads/move.html',
+        return self.request.theme.render_to_response('threads/move_threads.html',
                                                      {
                                                      {
                                                       'message': self.message,
                                                       'message': self.message,
                                                       'forum': self.forum,
                                                       'forum': self.forum,
@@ -238,7 +238,7 @@ class ThreadsView(BaseView):
             form = MergeThreadsForm(self.request.POST, request=self.request, threads=threads)
             form = MergeThreadsForm(self.request.POST, request=self.request, threads=threads)
             if form.is_valid():
             if form.is_valid():
                 new_thread = Thread.objects.create(
                 new_thread = Thread.objects.create(
-                                                   forum=self.forum,
+                                                   forum=form.cleaned_data['new_forum'],
                                                    name=form.cleaned_data['thread_name'],
                                                    name=form.cleaned_data['thread_name'],
                                                    slug=slugify(form.cleaned_data['thread_name']),
                                                    slug=slugify(form.cleaned_data['thread_name']),
                                                    start=timezone.now(),
                                                    start=timezone.now(),
@@ -259,6 +259,9 @@ class ThreadsView(BaseView):
                 new_thread.save(force_update=True)
                 new_thread.save(force_update=True)
                 self.forum.sync()
                 self.forum.sync()
                 self.forum.save(force_update=True)
                 self.forum.save(force_update=True)
+                if form.cleaned_data['new_forum'].pk != self.forum.pk:
+                    form.cleaned_data['new_forum'].sync()
+                    form.cleaned_data['new_forum'].save(force_update=True)
                 self.request.messages.set_flash(Message(_('Selected threads have been merged into new one.')), 'success', 'threads')
                 self.request.messages.set_flash(Message(_('Selected threads have been merged into new one.')), 'success', 'threads')
                 return None
                 return None
             self.message = Message(form.non_field_errors()[0], 'error')
             self.message = Message(form.non_field_errors()[0], 'error')

+ 2 - 2
misago/threads/views/thread.py

@@ -260,7 +260,7 @@ class ThreadView(BaseView):
             message = Message(form.non_field_errors()[0], 'error')
             message = Message(form.non_field_errors()[0], 'error')
         else:
         else:
             form = MovePostsForm(request=self.request)
             form = MovePostsForm(request=self.request)
-        return self.request.theme.render_to_response('threads/move.html',
+        return self.request.theme.render_to_response('threads/move_posts.html',
                                                      {
                                                      {
                                                       'message': message,
                                                       'message': message,
                                                       'forum': self.forum,
                                                       'forum': self.forum,
@@ -451,7 +451,7 @@ class ThreadView(BaseView):
             message = Message(form.non_field_errors()[0], 'error')
             message = Message(form.non_field_errors()[0], 'error')
         else:
         else:
             form = MoveThreadsForm(request=self.request, forum=self.forum)
             form = MoveThreadsForm(request=self.request, forum=self.forum)
-        return self.request.theme.render_to_response('threads/move.html',
+        return self.request.theme.render_to_response('threads/move_thread.html',
                                                      {
                                                      {
                                                       'message': message,
                                                       'message': message,
                                                       'forum': self.forum,
                                                       'forum': self.forum,

+ 1 - 1
misago/watcher/models.py

@@ -22,7 +22,7 @@ move_forum_content.connect(move_forum_content_handler, dispatch_uid="move_forum_
 
 
 
 
 def move_thread_handler(sender, **kwargs):
 def move_thread_handler(sender, **kwargs):
-    ThreadWatch.objects.filter(forum=sender.forum_pk).update(forum=kwargs['move_to'])
+    ThreadWatch.objects.filter(forum=sender.forum_id).update(forum=kwargs['move_to'])
 
 
 move_thread.connect(move_thread_handler, dispatch_uid="move_thread_watchers")
 move_thread.connect(move_thread_handler, dispatch_uid="move_thread_watchers")
 
 

+ 3 - 2
static/cranefly/css/cranefly.css

@@ -848,7 +848,7 @@ a.label:hover,a.label:focus,a.badge:hover,a.badge:focus{color:#ffffff;text-decor
 .show{display:block;}
 .show{display:block;}
 .invisible{visibility:hidden;}
 .invisible{visibility:hidden;}
 .affix{position:fixed;}
 .affix{position:fixed;}
-@media (min-width:1200px){.row{margin-left:-30px;*zoom:1;}.row:before,.row:after{display:table;content:"";line-height:0;} .row:after{clear:both;} [class*="span"]{float:left;min-height:1px;margin-left:30px;} .container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px;} .span12{width:1170px;} .span11{width:1070px;} .span10{width:970px;} .span9{width:870px;} .span8{width:770px;} .span7{width:670px;} .span6{width:570px;} .span5{width:470px;} .span4{width:370px;} .span3{width:270px;} .span2{width:170px;} .span1{width:70px;} .offset12{margin-left:1230px;} .offset11{margin-left:1130px;} .offset10{margin-left:1030px;} .offset9{margin-left:930px;} .offset8{margin-left:830px;} .offset7{margin-left:730px;} .offset6{margin-left:630px;} .offset5{margin-left:530px;} .offset4{margin-left:430px;} .offset3{margin-left:330px;} .offset2{margin-left:230px;} .offset1{margin-left:130px;} .row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0;} .row-fluid:after{clear:both;} .row-fluid [class*="span"]{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;} .row-fluid [class*="span"]:first-child{margin-left:0;} .row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.564102564102564%;} .row-fluid .span12{width:100%;*width:99.94680851063829%;} .row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%;} .row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%;} .row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%;} .row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%;} .row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%;} .row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%;} .row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%;} .row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%;} .row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%;} .row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%;} .row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%;} .row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%;} .row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%;} .row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%;} .row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%;} .row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%;} .row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%;} .row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%;} .row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%;} .row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%;} .row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%;} .row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%;} .row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%;} .row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%;} .row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%;} .row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%;} .row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%;} .row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%;} .row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%;} .row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%;} .row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%;} .row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%;} .row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%;} .row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%;} .row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%;} input,textarea,.uneditable-input{margin-left:0;} .controls-row [class*="span"]+[class*="span"]{margin-left:30px;} input.span12,textarea.span12,.uneditable-input.span12{width:1156px;} input.span11,textarea.span11,.uneditable-input.span11{width:1056px;} input.span10,textarea.span10,.uneditable-input.span10{width:956px;} input.span9,textarea.span9,.uneditable-input.span9{width:856px;} input.span8,textarea.span8,.uneditable-input.span8{width:756px;} input.span7,textarea.span7,.uneditable-input.span7{width:656px;} input.span6,textarea.span6,.uneditable-input.span6{width:556px;} input.span5,textarea.span5,.uneditable-input.span5{width:456px;} input.span4,textarea.span4,.uneditable-input.span4{width:356px;} input.span3,textarea.span3,.uneditable-input.span3{width:256px;} input.span2,textarea.span2,.uneditable-input.span2{width:156px;} input.span1,textarea.span1,.uneditable-input.span1{width:56px;} .thumbnails{margin-left:-30px;} .thumbnails>li{margin-left:30px;} .row-fluid .thumbnails{margin-left:0;}}.header-primary{background-color:#fbfbfb;border-bottom:1px solid #e7e7e7;margin:0px;margin-top:0px;padding-top:10px;}.header-primary .breadcrumb{background:none;border:none;margin:0px;margin-bottom:-11.9px;padding:0px;}.header-primary .breadcrumb li{font-size:11.9px;font-weight:bold;text-shadow:none;}.header-primary .breadcrumb li a:link,.header-primary .breadcrumb li a:visited{color:#999999;}
+@media (min-width:1200px){.row{margin-left:-30px;*zoom:1;}.row:before,.row:after{display:table;content:"";line-height:0;} .row:after{clear:both;} [class*="span"]{float:left;min-height:1px;margin-left:30px;} .container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px;} .span12{width:1170px;} .span11{width:1070px;} .span10{width:970px;} .span9{width:870px;} .span8{width:770px;} .span7{width:670px;} .span6{width:570px;} .span5{width:470px;} .span4{width:370px;} .span3{width:270px;} .span2{width:170px;} .span1{width:70px;} .offset12{margin-left:1230px;} .offset11{margin-left:1130px;} .offset10{margin-left:1030px;} .offset9{margin-left:930px;} .offset8{margin-left:830px;} .offset7{margin-left:730px;} .offset6{margin-left:630px;} .offset5{margin-left:530px;} .offset4{margin-left:430px;} .offset3{margin-left:330px;} .offset2{margin-left:230px;} .offset1{margin-left:130px;} .row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0;} .row-fluid:after{clear:both;} .row-fluid [class*="span"]{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;} .row-fluid [class*="span"]:first-child{margin-left:0;} .row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.564102564102564%;} .row-fluid .span12{width:100%;*width:99.94680851063829%;} .row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%;} .row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%;} .row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%;} .row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%;} .row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%;} .row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%;} .row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%;} .row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%;} .row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%;} .row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%;} .row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%;} .row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%;} .row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%;} .row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%;} .row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%;} .row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%;} .row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%;} .row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%;} .row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%;} .row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%;} .row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%;} .row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%;} .row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%;} .row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%;} .row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%;} .row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%;} .row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%;} .row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%;} .row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%;} .row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%;} .row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%;} .row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%;} .row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%;} .row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%;} .row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%;} input,textarea,.uneditable-input{margin-left:0;} .controls-row [class*="span"]+[class*="span"]{margin-left:30px;} input.span12,textarea.span12,.uneditable-input.span12{width:1156px;} input.span11,textarea.span11,.uneditable-input.span11{width:1056px;} input.span10,textarea.span10,.uneditable-input.span10{width:956px;} input.span9,textarea.span9,.uneditable-input.span9{width:856px;} input.span8,textarea.span8,.uneditable-input.span8{width:756px;} input.span7,textarea.span7,.uneditable-input.span7{width:656px;} input.span6,textarea.span6,.uneditable-input.span6{width:556px;} input.span5,textarea.span5,.uneditable-input.span5{width:456px;} input.span4,textarea.span4,.uneditable-input.span4{width:356px;} input.span3,textarea.span3,.uneditable-input.span3{width:256px;} input.span2,textarea.span2,.uneditable-input.span2{width:156px;} input.span1,textarea.span1,.uneditable-input.span1{width:56px;} .thumbnails{margin-left:-30px;} .thumbnails>li{margin-left:30px;} .row-fluid .thumbnails{margin-left:0;}}.header-primary{background-color:#fbfbfb;border-bottom:1px solid #e7e7e7;margin:0px;margin-top:0px;padding-top:10px;}.header-primary .breadcrumb{background:none;border:none;margin:0px;margin-bottom:-5.95px;padding:0px;}.header-primary .breadcrumb li{font-size:11.9px;font-weight:bold;text-shadow:none;}.header-primary .breadcrumb li a:link,.header-primary .breadcrumb li a:visited{color:#999999;}
 .header-primary .breadcrumb li a:hover,.header-primary .breadcrumb li a:active{color:#333333;}
 .header-primary .breadcrumb li a:hover,.header-primary .breadcrumb li a:active{color:#333333;}
 .header-primary .breadcrumb li .divider{padding-left:0px;padding-right:0px;}.header-primary .breadcrumb li .divider i{opacity:0.2;filter:alpha(opacity=20);position:relative;bottom:1px;}
 .header-primary .breadcrumb li .divider{padding-left:0px;padding-right:0px;}.header-primary .breadcrumb li .divider i{opacity:0.2;filter:alpha(opacity=20);position:relative;bottom:1px;}
 .header-primary h1{color:#555555;font-size:35px;font-weight:normal;}
 .header-primary h1{color:#555555;font-size:35px;font-weight:normal;}
@@ -1023,7 +1023,8 @@ a.btn-link:hover,a.btn-link:active,a.btn-link:focus{opacity:0.9;filter:alpha(opa
 .forum-subforums-list table .forum-main .forum-description{clear:both;margin:0px;padding:0px;color:#8c8c8c;font-size:11.9px;}
 .forum-subforums-list table .forum-main .forum-description{clear:both;margin:0px;padding:0px;color:#8c8c8c;font-size:11.9px;}
 .forum-subforums-list.forum-subforums-important caption{background-color:#cf402e;border:1px solid #ba3a29;text-shadow:0px 1px 0px #672017;}
 .forum-subforums-list.forum-subforums-important caption{background-color:#cf402e;border:1px solid #ba3a29;text-shadow:0px 1px 0px #672017;}
 .forum-threads-list{background-color:#ffffff;border:1px solid #d5d5d5;border-radius:2px;-webkit-box-shadow:0px 0px 0px 3px #eeeeee;-moz-box-shadow:0px 0px 0px 3px #eeeeee;box-shadow:0px 0px 0px 3px #eeeeee;margin-bottom:20px;}.forum-threads-list table{margin:0px;}.forum-threads-list table th{background-color:#fbfbfb;border-bottom:1px solid #eeeeee;padding:2px 10px;color:#999999;font-size:11.9px;}
 .forum-threads-list{background-color:#ffffff;border:1px solid #d5d5d5;border-radius:2px;-webkit-box-shadow:0px 0px 0px 3px #eeeeee;-moz-box-shadow:0px 0px 0px 3px #eeeeee;box-shadow:0px 0px 0px 3px #eeeeee;margin-bottom:20px;}.forum-threads-list table{margin:0px;}.forum-threads-list table th{background-color:#fbfbfb;border-bottom:1px solid #eeeeee;padding:2px 10px;color:#999999;font-size:11.9px;}
-.forum-threads-list table td{vertical-align:middle;}.forum-threads-list table td .thread-icon:link,.forum-threads-list table td .thread-icon:active,.forum-threads-list table td .thread-icon:visited,.forum-threads-list table td .thread-icon:hover{background-color:#555555;border:1px solid #2f2f2f;border-radius:3px;padding:3px 4px;}.forum-threads-list table td .thread-icon:link.thread-new,.forum-threads-list table td .thread-icon:active.thread-new,.forum-threads-list table td .thread-icon:visited.thread-new,.forum-threads-list table td .thread-icon:hover.thread-new{background-color:#cf402e;border:1px solid #902d20;}
+.forum-threads-list table td{vertical-align:middle;}.forum-threads-list table td.threads-list-empty{padding:11px 19px;font-size:17.5px;text-align:center;}
+.forum-threads-list table td .thread-icon:link,.forum-threads-list table td .thread-icon:active,.forum-threads-list table td .thread-icon:visited,.forum-threads-list table td .thread-icon:hover{background-color:#555555;border:1px solid #2f2f2f;border-radius:3px;padding:3px 4px;}.forum-threads-list table td .thread-icon:link.thread-new,.forum-threads-list table td .thread-icon:active.thread-new,.forum-threads-list table td .thread-icon:visited.thread-new,.forum-threads-list table td .thread-icon:hover.thread-new{background-color:#cf402e;border:1px solid #902d20;}
 .forum-threads-list table td .thread-icon i{background-image:url("../img/glyphicons-halflings-white.png");}
 .forum-threads-list table td .thread-icon i{background-image:url("../img/glyphicons-halflings-white.png");}
 .forum-threads-list table td .thread-name{color:#333333;font-weight:bold;}
 .forum-threads-list table td .thread-name{color:#333333;font-weight:bold;}
 .forum-threads-list table td .thread-details,.forum-threads-list table td .thread-last-reply{color:#999999;}.forum-threads-list table td .thread-details a:link,.forum-threads-list table td .thread-last-reply a:link,.forum-threads-list table td .thread-details a:visited,.forum-threads-list table td .thread-last-reply a:visited{color:#333333;}
 .forum-threads-list table td .thread-details,.forum-threads-list table td .thread-last-reply{color:#999999;}.forum-threads-list table td .thread-details a:link,.forum-threads-list table td .thread-last-reply a:link,.forum-threads-list table td .thread-details a:visited,.forum-threads-list table td .thread-last-reply a:visited{color:#333333;}

+ 1 - 0
static/cranefly/css/cranefly.less

@@ -87,6 +87,7 @@
 @import "cranefly/category.less";
 @import "cranefly/category.less";
 @import "cranefly/profiles.less";
 @import "cranefly/profiles.less";
 @import "cranefly/forum.less";
 @import "cranefly/forum.less";
+@import "cranefly/thread.less";
 
 
 // Keep ranks last for easy overrides!
 // Keep ranks last for easy overrides!
 @import "ranks.less";
 @import "ranks.less";

+ 7 - 0
static/cranefly/css/cranefly/forum.less

@@ -118,6 +118,13 @@
     td {
     td {
       vertical-align: middle;
       vertical-align: middle;
 
 
+      &.threads-list-empty {
+        padding: @paddingLarge;
+
+        font-size: @fontSizeLarge;
+        text-align: center;
+      }
+
       .thread-icon {
       .thread-icon {
         &:link, &:active, &:visited, &:hover {
         &:link, &:active, &:visited, &:hover {
           background-color: @itemOldColor;
           background-color: @itemOldColor;

+ 1 - 1
static/cranefly/css/cranefly/header.less

@@ -11,7 +11,7 @@
     background: none;
     background: none;
     border: none;
     border: none;
     margin: 0px;
     margin: 0px;
-    margin-bottom: @fontSizeSmall * -1;
+    margin-bottom: @fontSizeSmall * -0.5;
     padding: 0px;
     padding: 0px;
 
 
     li {
     li {

+ 2 - 0
static/cranefly/css/cranefly/thread.less

@@ -0,0 +1,2 @@
+// Thread view
+// -------------------------

+ 6 - 0
templates/cranefly/threads/list.html

@@ -139,6 +139,12 @@
           <td class="check-cell">{% if thread.forum_id == forum.pk %}<label class="checkbox"><input form="threads_form" name="{{ list_form['list_items']['html_name'] }}" type="checkbox" class="checkbox-member" value="{{ thread.pk }}"{% if list_form['list_items']['has_value'] and ('' ~ thread.pk) in list_form['list_items']['value'] %} checked="checked"{% endif %}></label>{% else %}&nbsp;{% endif %}</td>
           <td class="check-cell">{% if thread.forum_id == forum.pk %}<label class="checkbox"><input form="threads_form" name="{{ list_form['list_items']['html_name'] }}" type="checkbox" class="checkbox-member" value="{{ thread.pk }}"{% if list_form['list_items']['has_value'] and ('' ~ thread.pk) in list_form['list_items']['value'] %} checked="checked"{% endif %}></label>{% else %}&nbsp;{% endif %}</td>
           {% endif %}
           {% endif %}
         </tr>
         </tr>
+        {% else %}
+        <tr>
+          <td colspan="4" class="threads-list-empty">
+            {% trans %}There are no threads in this forum.{% endtrans %}
+          </td>
+        </tr>
         {% endfor %}
         {% endfor %}
       </tbody>
       </tbody>
     </table>
     </table>

+ 50 - 3
templates/cranefly/threads/merge.html

@@ -6,14 +6,61 @@
 
 
 {% block title %}{{ macros.page_title(title=_("Merge Threads"),parent=forum.name) }}{% endblock %}
 {% block title %}{{ macros.page_title(title=_("Merge Threads"),parent=forum.name) }}{% endblock %}
 
 
-{% block breadcrumb %}{{ super() }} <span class="divider">/</span></li>
+{% block breadcrumb %}{{ super() }} <span class="divider"><i class="icon-chevron-right"></i></span></li>
 {% for parent in parents %}
 {% for parent in parents %}
-<li class="first"><a href="{{ parent.type|url(forum=parent.pk, slug=parent.slug) }}">{{ parent.name }}</a> <span class="divider">/</span></li>
+<li><a href="{{ parent.type|url(forum=parent.pk, slug=parent.slug) }}">{{ parent.name }}</a> <span class="divider"><i class="icon-chevron-right"></i></span></li>
 {% endfor %}
 {% endfor %}
-<li class="first"><a href="{% url 'forum' forum=forum.pk, slug=forum.slug %}">{{ forum.name }}</a> <span class="divider">/</span></li>
+<li><a href="{{ forum.type|url(forum=forum.pk, slug=forum.slug) }}">{{ forum.name }}</a> <span class="divider"><i class="icon-chevron-right"></i></span></li>
 <li class="active">{% trans %}Merge Threads{% endtrans %}
 <li class="active">{% trans %}Merge Threads{% endtrans %}
 {%- endblock %}
 {%- endblock %}
 
 
+{% block container %}
+<div class="page-header header-primary">
+  <div class="container">
+    {{ messages_list(messages) }}
+    <ul class="breadcrumb">
+      {{ self.breadcrumb() }}</li>
+    </ul>
+    <h1>{% trans %}Merge Threads{% endtrans %} <small>{{ forum.name }}</small></h1>
+  </div>
+</div>
+
+<div class="container container-primary">
+  <div class="row">
+    <div class="span6 offset3">
+      <div class="form-container">
+
+        <div class="form-header">
+          <h1>{% trans %}Merge Threads{% endtrans %}</h1>
+        </div>
+
+        {% if message %}
+        <div class="messages-list">
+          {{ macros.draw_message(message) }}
+        </div>
+        {% endif %}
+
+        <form action="{% url 'forum' forum=forum.pk, slug=forum.slug %}" method="post">
+          <input type="hidden" name="origin" value="merge_form">
+          <input type="hidden" name="list_action" value="merge">
+          {% for thread in threads -%}
+          <input type="hidden" name="list_items" value="{{ thread.pk }}">
+          {% endfor %}
+          <div class="form-fields">
+            {{ form_theme.form_widget(form, width=6) }}
+          </div>
+          <div class="form-actions">
+            <button type="submit" class="btn btn-primary">{% trans %}Merge Threads{% endtrans %}</button>
+            <a href="{% url 'forum' forum=forum.pk, slug=forum.slug %}" class="btn">{% trans %}Cancel{% endtrans %}</a>
+          </div>
+        </form>
+
+      </div>
+    </div>
+  </div>
+</div>
+{% endblock %}
+
 {% block content %}
 {% block content %}
 <div class="page-header">
 <div class="page-header">
   <ul class="breadcrumb">
   <ul class="breadcrumb">

+ 0 - 43
templates/cranefly/threads/move.html

@@ -1,43 +0,0 @@
-{% extends "cranefly/layout.html" %}
-{% load i18n %}
-{% load url from future %}
-{% import "_forms.html" as form_theme with context %}
-{% import "cranefly/macros.html" as macros with context %}
-
-{% block title %}{{ macros.page_title(title=_("Move Posts"),parent=thread.name) }}{% endblock %}
-
-{% block breadcrumb %}{{ super() }} <span class="divider">/</span></li>
-{% for parent in parents %}
-<li class="first"><a href="{{ parent.type|url(forum=parent.pk, slug=parent.slug) }}">{{ parent.name }}</a> <span class="divider">/</span></li>
-{% endfor %}
-<li><a href="{% url 'thread' thread=thread.pk, slug=thread.slug %}">{{ thread.name }}</a> <span class="divider">/</span></li>
-<li class="active">{% trans %}Move Posts{% endtrans %}
-{%- endblock %}
-
-{% block content %}
-<div class="page-header">
-  <ul class="breadcrumb">
-    {{ self.breadcrumb() }}</li>
-  </ul>
-  <h1>{% trans %}Move Posts{% endtrans %} <small>{{ thread.name }}</small></h1>
-</div>
-<div class="row">
-  <div class="span8 offset2">
-    {% if message %}{{ macros.draw_message(message) }}{% endif %}
-    <form action="{% url 'thread' thread=thread.pk, slug=thread.slug %}" method="post">
-      <input type="hidden" name="{{ csrf_id }}" value="{{ csrf_token }}">
-      <input type="hidden" name="origin" value="posts_form">
-      <input type="hidden" name="list_action" value="move">
-      <input type="hidden" name="do" value="move">
-      {% for post in posts -%}
-      <input type="hidden" name="list_items" value="{{ post }}">
-      {% endfor %}
-      {{ form_theme.form_widget(form, width=8) }}
-      <div class="form-actions">
-        <button name="save" type="submit" class="btn btn-primary">{% trans %}Move Posts{% endtrans %}</button>
-        <a href="{% url 'thread' thread=thread.pk, slug=thread.slug %}" class="btn">{% trans %}Cancel{% endtrans %}</a>
-      </div>
-    </form>
-  </div>
-</div>
-{% endblock %}

+ 63 - 0
templates/cranefly/threads/move_posts.html

@@ -0,0 +1,63 @@
+{% extends "cranefly/layout.html" %}
+{% load i18n %}
+{% load url from future %}
+{% import "_forms.html" as form_theme with context %}
+{% import "cranefly/macros.html" as macros with context %}
+
+{% block title %}{{ macros.page_title(title=_("Move Posts"),parent=thread.name) }}{% endblock %}
+
+{% block breadcrumb %}{{ super() }} <span class="divider"><i class="icon-chevron-right"></i></span></li>
+{% for parent in parents %}
+<li><a href="{{ parent.type|url(forum=parent.pk, slug=parent.slug) }}">{{ parent.name }}</a> <span class="divider"><i class="icon-chevron-right"></i></span></li>
+{% endfor %}
+<li><a href="{% url 'thread' thread=thread.pk, slug=thread.slug %}">{{ thread.name }}</a> <span class="divider"><i class="icon-chevron-right"></i></span></li>
+<li class="active">{% trans %}Move Posts{% endtrans %}
+{%- endblock %}
+
+{% block container %}
+<div class="page-header header-primary">
+  <div class="container">
+    {{ messages_list(messages) }}
+    <ul class="breadcrumb">
+      {{ self.breadcrumb() }}</li>
+    </ul>
+    <h1>{% trans %}Move Posts{% endtrans %} <small>{{ thread.name }}</small></h1>
+  </div>
+</div>
+
+<div class="container container-primary">
+  <div class="row">
+    <div class="span6 offset3">
+      <div class="form-container">
+
+        <div class="form-header">
+          <h1>{% trans %}Move Posts{% endtrans %}</h1>
+        </div>
+
+        {% if message %}
+        <div class="messages-list">
+          {{ macros.draw_message(message) }}
+        </div>
+        {% endif %}
+
+        <form action="{% url 'thread' thread=thread.pk, slug=thread.slug %}" method="post">
+          <input type="hidden" name="origin" value="posts_form">
+          <input type="hidden" name="list_action" value="move">
+          <input type="hidden" name="do" value="move">
+          {% for post in posts -%}
+          <input type="hidden" name="list_items" value="{{ post }}">
+          {% endfor %}
+          <div class="form-fields">
+            {{ form_theme.form_widget(form, width=6) }}
+          </div>
+          <div class="form-actions">
+            <button type="submit" class="btn btn-primary">{% trans %}Move Posts{% endtrans %}</button>
+            <a href="{% url 'thread' thread=thread.pk, slug=thread.slug %}" class="btn">{% trans %}Cancel{% endtrans %}</a>
+          </div>
+        </form>
+
+      </div>
+    </div>
+  </div>
+</div>
+{% endblock %}

+ 64 - 0
templates/cranefly/threads/move_thread.html

@@ -0,0 +1,64 @@
+{% extends "cranefly/layout.html" %}
+{% load i18n %}
+{% load url from future %}
+{% import "_forms.html" as form_theme with context %}
+{% import "cranefly/macros.html" as macros with context %}
+
+{% block title %}{{ macros.page_title(title=_("Move Threads"),parent=forum.name) }}{% endblock %}
+
+{% block breadcrumb %}{{ super() }} <span class="divider"><i class="icon-chevron-right"></i></span></li>
+{% for parent in parents %}
+<li><a href="{{ parent.type|url(forum=parent.pk, slug=parent.slug) }}">{{ parent.name }}</a> <span class="divider"><i class="icon-chevron-right"></i></span></li>
+{% endfor %}
+<li><a href="{% url 'thread' thread=thread.pk, slug=thread.slug %}">{{ thread.name }}</a> <span class="divider"><i class="icon-chevron-right"></i></span></li>
+<li class="active">{% trans %}Move Thread{% endtrans %}
+{%- endblock %}
+
+{% block container %}
+<div class="page-header header-primary">
+  <div class="container">
+    {{ messages_list(messages) }}
+    <ul class="breadcrumb">
+      {{ self.breadcrumb() }}</li>
+    </ul>
+    <h1>{% trans %}Move Thread{% endtrans %} <small>{{ thread.name }}</small></h1>
+  </div>
+</div>
+
+<div class="container container-primary">
+  <div class="row">
+    <div class="span6 offset3">
+      <div class="form-container">
+
+        <div class="form-header">
+          <h1>{% trans %}Move Thread{% endtrans %}</h1>
+        </div>
+
+        {% if message %}
+        <div class="messages-list">
+          {{ macros.draw_message(message) }}
+        </div>
+        {% endif %}
+
+        <form action="{% url 'thread' thread=thread.pk, slug=thread.slug %}" method="post">
+          <input type="hidden" name="origin" value="thread_form">
+          <input type="hidden" name="thread_action" value="move">
+          <input type="hidden" name="do" value="move">
+          {% for thread in threads -%}
+          <input type="hidden" name="list_items" value="{{ thread.pk }}">
+          {% endfor %}
+          <div class="form-fields">
+            {% do form.fieldsets[0]['fields'][0].update({'label': _("Move Thread To"), 'help_text': _("Select forum you want to move this thread to.")}) %}
+            {{ form_theme.form_widget(form, width=6) }}
+          </div>
+          <div class="form-actions">
+            <button type="submit" class="btn btn-primary">{% trans %}Move Thread{% endtrans %}</button>
+            <a href="{% url 'thread' thread=thread.pk, slug=thread.slug %}" class="btn">{% trans %}Cancel{% endtrans %}</a>
+          </div>
+        </form>
+
+      </div>
+    </div>
+  </div>
+</div>
+{% endblock %}

+ 62 - 0
templates/cranefly/threads/move_threads.html

@@ -0,0 +1,62 @@
+{% extends "cranefly/layout.html" %}
+{% load i18n %}
+{% load url from future %}
+{% import "_forms.html" as form_theme with context %}
+{% import "cranefly/macros.html" as macros with context %}
+
+{% block title %}{{ macros.page_title(title=_("Move Threads"),parent=forum.name) }}{% endblock %}
+
+{% block breadcrumb %}{{ super() }} <span class="divider"><i class="icon-chevron-right"></i></span></li>
+{% for parent in parents %}
+<li><a href="{{ parent.type|url(forum=parent.pk, slug=parent.slug) }}">{{ parent.name }}</a> <span class="divider"><i class="icon-chevron-right"></i></span></li>
+{% endfor %}
+<li><a href="{{ forum.type|url(forum=forum.pk, slug=forum.slug) }}">{{ forum.name }}</a> <span class="divider"><i class="icon-chevron-right"></i></span></li>
+<li class="active">{% trans %}Move Threads{% endtrans %}
+{%- endblock %}
+
+{% block container %}
+<div class="page-header header-primary">
+  <div class="container">
+    {{ messages_list(messages) }}
+    <ul class="breadcrumb">
+      {{ self.breadcrumb() }}</li>
+    </ul>
+    <h1>{% trans %}Move Threads{% endtrans %} <small>{{ forum.name }}</small></h1>
+  </div>
+</div>
+
+<div class="container container-primary">
+  <div class="row">
+    <div class="span6 offset3">
+      <div class="form-container">
+
+        <div class="form-header">
+          <h1>{% trans %}Move Threads{% endtrans %}</h1>
+        </div>
+
+        {% if message %}
+        <div class="messages-list">
+          {{ macros.draw_message(message) }}
+        </div>
+        {% endif %}
+
+        <form action="{% url 'forum' forum=forum.pk, slug=forum.slug %}" method="post">
+          <input type="hidden" name="origin" value="move_form">
+          <input type="hidden" name="list_action" value="move">
+          {% for thread in threads -%}
+          <input type="hidden" name="list_items" value="{{ thread.pk }}">
+          {% endfor %}
+          <div class="form-fields">
+            {{ form_theme.form_widget(form, width=6) }}
+          </div>
+          <div class="form-actions">
+            <button type="submit" class="btn btn-primary">{% trans %}Move Threads{% endtrans %}</button>
+            <a href="{% url 'forum' forum=forum.pk, slug=forum.slug %}" class="btn">{% trans %}Cancel{% endtrans %}</a>
+          </div>
+        </form>
+
+      </div>
+    </div>
+  </div>
+</div>
+{% endblock %}

+ 45 - 25
templates/cranefly/threads/split.html

@@ -6,38 +6,58 @@
 
 
 {% block title %}{{ macros.page_title(title=_("Split Thread"),parent=thread.name) }}{% endblock %}
 {% block title %}{{ macros.page_title(title=_("Split Thread"),parent=thread.name) }}{% endblock %}
 
 
-{% block breadcrumb %}{{ super() }} <span class="divider">/</span></li>
+{% block breadcrumb %}{{ super() }} <span class="divider"><i class="icon-chevron-right"></i></span></li>
 {% for parent in parents %}
 {% for parent in parents %}
-<li class="first"><a href="{{ parent.type|url(forum=parent.pk, slug=parent.slug) }}">{{ parent.name }}</a> <span class="divider">/</span></li>
+<li><a href="{{ parent.type|url(forum=parent.pk, slug=parent.slug) }}">{{ parent.name }}</a> <span class="divider"><i class="icon-chevron-right"></i></span></li>
 {% endfor %}
 {% endfor %}
-<li><a href="{% url 'thread' thread=thread.pk, slug=thread.slug %}">{{ thread.name }}</a> <span class="divider">/</span></li>
+<li><a href="{% url 'thread' thread=thread.pk, slug=thread.slug %}">{{ thread.name }}</a> <span class="divider"><i class="icon-chevron-right"></i></span></li>
 <li class="active">{% trans %}Split Thread{% endtrans %}
 <li class="active">{% trans %}Split Thread{% endtrans %}
 {%- endblock %}
 {%- endblock %}
 
 
-{% block content %}
-<div class="page-header">
-  <ul class="breadcrumb">
-    {{ self.breadcrumb() }}</li>
-  </ul>
-  <h1>{% trans %}Split Thread{% endtrans %} <small>{{ thread.name }}</small></h1>
+{% block container %}
+<div class="page-header header-primary">
+  <div class="container">
+    {{ messages_list(messages) }}
+    <ul class="breadcrumb">
+      {{ self.breadcrumb() }}</li>
+    </ul>
+    <h1>{% trans %}Split Thread{% endtrans %} <small>{{ thread.name }}</small></h1>
+  </div>
 </div>
 </div>
-<div class="row">
-  <div class="span8 offset2">
-    {% if message %}{{ macros.draw_message(message) }}{% endif %}
-    <form action="{% url 'thread' thread=thread.pk, slug=thread.slug %}" method="post">
-      <input type="hidden" name="{{ csrf_id }}" value="{{ csrf_token }}">
-      <input type="hidden" name="origin" value="posts_form">
-      <input type="hidden" name="list_action" value="split">
-      <input type="hidden" name="do" value="split">
-      {% for post in posts -%}
-      <input type="hidden" name="list_items" value="{{ post }}">
-      {% endfor %}
-      {{ form_theme.form_widget(form, width=8) }}
-      <div class="form-actions">
-        <button name="save" type="submit" class="btn btn-primary">{% trans %}Split Thread{% endtrans %}</button>
-        <a href="{% url 'thread' thread=thread.pk, slug=thread.slug %}" class="btn">{% trans %}Cancel{% endtrans %}</a>
+
+<div class="container container-primary">
+  <div class="row">
+    <div class="span6 offset3">
+      <div class="form-container">
+
+        <div class="form-header">
+          <h1>{% trans %}Split Thread{% endtrans %}</h1>
+        </div>
+
+        {% if message %}
+        <div class="messages-list">
+          {{ macros.draw_message(message) }}
+        </div>
+        {% endif %}
+
+        <form action="{% url 'thread' thread=thread.pk, slug=thread.slug %}" method="post">
+          <input type="hidden" name="origin" value="posts_form">
+          <input type="hidden" name="list_action" value="split">
+          <input type="hidden" name="do" value="split">
+          {% for post in posts -%}
+          <input type="hidden" name="list_items" value="{{ post }}">
+          {% endfor %}
+          <div class="form-fields">
+            {{ form_theme.form_widget(form, width=6) }}
+          </div>
+          <div class="form-actions">
+            <button type="submit" class="btn btn-primary">{% trans %}Split Thread{% endtrans %}</button>
+            <a href="{% url 'thread' thread=thread.pk, slug=thread.slug %}" class="btn">{% trans %}Cancel{% endtrans %}</a>
+          </div>
+        </form>
+
       </div>
       </div>
-    </form>
+    </div>
   </div>
   </div>
 </div>
 </div>
 {% endblock %}
 {% endblock %}