Changeset 1077

Show
Ignore:
Timestamp:
08/01/06 19:05:28 (2 years ago)
Author:
Blackhex
Message:

DiscussionPlugin:

  • Edit posts functionality.
  • Bug #561 fix.
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • discussionplugin/0.9/tracdiscussion/api.py

    r1072 r1077  
    22from trac.web.chrome import add_stylesheet 
    33from trac.wiki import wiki_to_html, wiki_to_oneliner 
     4from trac.perm import PermissionError 
    45from trac.util import format_datetime, pretty_timedelta, escape, unescape, \ 
    56  Markup 
    6 from trac.util import Markup, format_datetime 
    77import time 
    88 
     
    127127                    else: 
    128128                        return ['message-post-add', 'message-list'] 
     129                elif action == 'edit': 
     130                    return ['message-edit', 'message-list'] 
     131                elif action == 'post-edit': 
     132                    if preview: 
     133                        return ['message-list'] 
     134                    else: 
     135                        return ['message-post-edit', 'message-list'] 
    129136                elif action == 'delete': 
    130137                    return ['message-delete', 'message-list'] 
     
    141148                    else: 
    142149                        return ['message-post-add', 'message-list'] 
     150                elif action == 'edit': 
     151                    return ['message-edit', 'message-list'] 
     152                elif action == 'post-edit': 
     153                    if preview: 
     154                        return ['message-list'] 
     155                    else: 
     156                        return ['message-post-edit', 'message-list'] 
    143157                elif action == 'delete': 
    144158                    return ['message-delete', 'message-list'] 
     
    158172                    else: 
    159173                        return ['message-post-add', 'message-list'] 
     174                elif action == 'edit': 
     175                    return ['topic-edit', 'message-list'] 
     176                elif action == 'post-edit': 
     177                    if preview: 
     178                        return ['message-list'] 
     179                    else: 
     180                        return ['topic-post-edit', 'message-list'] 
    160181                elif action == 'delete': 
    161182                    self.req.hdf['discussion.no_display'] = True 
     
    173194                    else: 
    174195                        return ['message-post-add', 'message-list'] 
     196                elif action == 'edit': 
     197                    return ['topic-edit', 'message-list'] 
     198                elif action == 'post-edit': 
     199                    if preview: 
     200                        return ['message-list'] 
     201                    else: 
     202                        return ['topic-post-edit', 'message-list'] 
    175203                elif action == 'delete': 
    176204                    return ['topic-delete', 'topic-list'] 
     
    242270        for mode in modes: 
    243271            self.log.debug('doing %s mode action' % (mode,)) 
    244             self.log.debug(forum) 
    245272            if mode == 'group-list': 
    246273                self.req.perm.assert_permission('DISCUSSION_VIEW') 
     274 
     275                # Display groups. 
    247276                self.req.hdf['discussion.groups'] = self.get_groups() 
     277 
    248278            elif mode == 'admin-group-list': 
    249279                self.req.perm.assert_permission('DISCUSSION_ADMIN') 
     280 
     281                # Display groups. 
    250282                if group: 
    251283                    self.req.hdf['discussion.name'] = group['name'] 
    252284                    self.req.hdf['discussion.description'] = group['description'] 
    253285                self.req.hdf['discussion.groups'] = self.get_groups() 
     286 
    254287            elif mode == 'group-add': 
    255288                self.req.perm.assert_permission('DISCUSSION_ADMIN') 
     289 
    256290            elif mode == 'group-post-add': 
    257291                self.req.perm.assert_permission('DISCUSSION_ADMIN') 
    258                 name = Markup(self.req.args.get('name')) 
    259                 description = Markup(self.req.args.get('description')) 
    260                 self.add_group(name, description) 
     292 
     293                # Get form values. 
     294                new_name = Markup(self.req.args.get('name')) 
     295                new_description = Markup(self.req.args.get('description')) 
     296 
     297                # Add new group. 
     298                self.add_group(new_name, new_description) 
     299 
    261300            elif mode == 'group-post-edit': 
    262301                self.req.perm.assert_permission('DISCUSSION_ADMIN') 
    263                 group = self.req.args.get('group') 
    264                 name = Markup(self.req.args.get('name')) 
    265                 description = Markup(self.req.args.get('description')) 
    266                 self.edit_group(group, name, description) 
     302 
     303                # Get form values. 
     304                new_group = self.req.args.get('group') 
     305                new_name = Markup(self.req.args.get('name')) 
     306                new_description = Markup(self.req.args.get('description')) 
     307 
     308                # Edit group. 
     309                self.edit_group(new_group, new_name, new_description) 
     310 
    267311            elif mode == 'group-delete': 
    268312                self.req.perm.assert_permission('DISCUSSION_ADMIN') 
     313 
    269314            elif mode == 'groups-delete': 
    270315                self.req.perm.assert_permission('DISCUSSION_ADMIN') 
     316 
     317                # Get selected groups. 
    271318                selection = self.req.args.get('selection') 
    272319                if isinstance(selection, (str, unicode)): 
    273320                    selection = [selection] 
     321 
     322                # Delete selected groups. 
    274323                if selection: 
    275324                    for group in selection: 
    276325                        self.delete_group(group) 
     326 
    277327            elif mode == 'forum-list': 
    278328                self.req.perm.assert_permission('DISCUSSION_VIEW') 
     329 
     330                # Display forums. 
    279331                self.req.hdf['discussion.groups'] = self.get_groups() 
    280332                self.req.hdf['discussion.forums'] = self.get_forums() 
     333 
    281334            elif mode == 'admin-forum-list': 
    282335                self.req.perm.assert_permission('DISCUSSION_ADMIN') 
     336 
     337                # Display forums. 
    283338                if forum: 
    284339                    self.req.hdf['discussion.name'] = forum['name'] 
     
    290345                self.req.hdf['discussion.groups'] = self.get_groups() 
    291346                self.req.hdf['discussion.forums'] = self.get_forums() 
     347 
    292348            elif mode == 'forum-add': 
    293349                self.req.perm.assert_permission('DISCUSSION_ADMIN') 
     350 
     351                # Display Add Forum form. 
    294352                self.req.hdf['discussion.users'] = self.get_users() 
    295353                self.req.hdf['discussion.groups'] = self.get_groups() 
     354 
    296355            elif mode == 'forum-post-add': 
    297356                self.req.perm.assert_permission('DISCUSSION_ADMIN') 
     357 
    298358                # Get form values 
    299359                new_name = Markup(self.req.args.get('name')) 
     
    307367                if not isinstance(new_moderators, list): 
    308368                     new_moderators = [new_moderators] 
     369 
    309370                # Perform new forum add. 
    310371                self.add_forum(new_name, new_author, new_subject, 
    311372                   new_description, new_moderators, new_group) 
     373 
    312374            elif mode == 'forum-post-edit': 
    313375                self.req.perm.assert_permission('DISCUSSION_ADMIN') 
     376 
    314377                # Get form values. 
    315378                new_forum = self.req.args.get('forum') 
     
    323386                if not isinstance(new_moderators, list): 
    324387                    new_moderators = [new_moderators] 
     388 
    325389                # Perform forum edit. 
    326390                self.edit_forum(new_forum, new_name, new_subject, 
    327391                  new_description, new_moderators, new_group) 
     392 
    328393            elif mode == 'forum-delete': 
    329394                self.req.perm.assert_permission('DISCUSSION_ADMIN') 
     395 
     396                # Delete forum 
    330397                self.delete_forum(forum['id']) 
     398 
    331399            elif mode == 'forums-delete': 
    332400                self.req.perm.assert_permission('DISCUSSION_ADMIN') 
     401 
     402                # Get selected forums. 
    333403                selection = self.req.args.get('selection') 
    334404                if isinstance(selection, (str, unicode)): 
    335405                    selection = [selection] 
     406 
     407                # Delete selected forums. 
    336408                if selection: 
    337409                    for forum in selection: 
    338410                        self.delete_forum(forum) 
     411 
    339412            elif mode == 'topic-list': 
    340413                self.req.perm.assert_permission('DISCUSSION_VIEW') 
     414 
     415                # Display topics. 
    341416                self.req.hdf['discussion.topics'] = self.get_topics(forum['id']) 
     417 
    342418            elif mode == 'topic-add': 
    343419                self.req.perm.assert_permission('DISCUSSION_APPEND') 
    344                 subject = Markup(self.req.args.get('subject')) 
    345                 author = Markup(self.req.args.get('author')) 
    346                 body = Markup(self.req.args.get('body')) 
    347                 if subject: 
     420 
     421                # Get form values. 
     422                new_subject = Markup(self.req.args.get('subject')) 
     423                new_author = Markup(self.req.args.get('author')) 
     424                new_body = Markup(self.req.args.get('body')) 
     425 
     426                # Display Add Topic form. 
     427                if new_subject: 
    348428                    self.req.hdf['discussion.subject'] = wiki_to_oneliner( 
    349                       subject, self.env) 
    350                 if author: 
    351                     self.req.hdf['discussion.author'] = wiki_to_oneliner(author, 
    352                       self.env) 
    353                 if body: 
    354                     self.req.hdf['discussion.body'] = wiki_to_html(body, 
     429                      new_subject, self.env) 
     430                if new_author: 
     431                    self.req.hdf['discussion.author'] = wiki_to_oneliner( 
     432                     new_author, self.env) 
     433                if new_body: 
     434                    self.req.hdf['discussion.body'] = wiki_to_html(new_body, 
    355435                      self.env, self.req) 
     436 
    356437            elif mode == 'topic-quote': 
    357438                self.req.perm.assert_permission('DISCUSSION_APPEND') 
     439 
     440                # Prepare old content. 
    358441                lines = topic['body'].splitlines() 
    359442                for I in xrange(len(lines)): 
    360443                    lines[I] = '> %s' % (lines[I]) 
    361444                self.req.hdf['args.body'] = '\n'.join(lines) 
     445 
    362446            elif mode == 'topic-post-add': 
    363447                self.req.perm.assert_permission('DISCUSSION_APPEND') 
    364                 subject = Markup(self.req.args.get('subject')) 
    365                 author = Markup(self.req.args.get('author')) 
    366                 body = Markup(self.req.args.get('body')) 
    367                 self.add_topic(forum['id'], subject, author, body) 
     448 
     449                # Get form values. 
     450                new_subject = Markup(self.req.args.get('subject')) 
     451                new_author = Markup(self.req.args.get('author')) 
     452                new_body = Markup(self.req.args.get('body')) 
     453 
     454                # Add topic. 
     455                self.add_topic(forum['id'], new_subject, new_author, new_body) 
     456 
     457            elif mode == 'topic-edit': 
     458                 self.req.perm.assert_permission('DISCUSSION_APPEND') 
     459                 if not is_moderator and (topic['author'] != self.req.authname): 
     460                    raise PermissionError('Topic edit') 
     461 
     462                 # Prepare form values. 
     463                 self.req.hdf['args.body'] = topic['body'] 
     464                 self.req.hdf['args.subject'] = topic['subject'] 
     465            elif mode == 'topic-post-edit': 
     466                 self.req.perm.assert_permission('DISCUSSION_APPEND') 
     467                 if not is_moderator and (topic['author'] != self.req.authname): 
     468                    raise PermissionError('Topic edit') 
     469 
     470                 # Get form values. 
     471                 new_subject = Markup(self.req.args.get('subject')) 
     472                 new_body = Markup(self.req.args.get('body')) 
     473 
     474                 # Edit topic. 
     475                 topic['subject'] = new_subject 
     476                 topic['body'] = new_body 
     477                 self.edit_topic(topic['id'], topic['forum'], new_subject, 
     478                   new_body) 
     479 
    368480            elif mode == 'topic-move': 
    369481                self.req.perm.assert_permission('DISCUSSION_MODERATE') 
    370482                if not is_moderator: 
    371483                    raise PermissionError('Forum moderate') 
     484 
     485                # Display Move Topic form 
    372486                self.req.hdf['discussion.forums'] = self.get_forums() 
     487 
    373488            elif mode == 'topic-post-move': 
    374489                self.req.perm.assert_permission('DISCUSSION_MODERATE') 
    375490                if not is_moderator: 
    376491                    raise PermissionError('Forum moderate') 
     492 
     493                # Get form values 
    377494                new_forum = self.req.args.get('new_forum') 
     495 
     496                # Move topic. 
    378497                self.set_forum(topic['id'], new_forum) 
     498 
    379499            elif mode == 'topic-delete': 
    380500                self.req.perm.assert_permission('DISCUSSION_MODERATE') 
    381501                if not is_moderator: 
    382502                    raise PermissionError('Forum moderate') 
     503 
     504                # Delete topic. 
    383505                self.delete_topic(topic['id']) 
     506 
    384507            elif mode == 'message-list': 
    385508                self.req.perm.assert_permission('DISCUSSION_VIEW') 
    386                 author = Markup(self.req.args.get('author')) 
    387                 body = Markup(self.req.args.get('body')) 
    388                 if author: 
    389                     self.req.hdf['discussion.author'] = wiki_to_oneliner(author, 
    390                       self.env) 
    391                 if body: 
    392                     self.req.hdf['discussion.body'] = wiki_to_html(body, 
     509 
     510                # Get form values. 
     511                new_author = Markup(self.req.args.get('author')) 
     512                new_subject = Markup(self.req.args.get('subject')) 
     513                new_body = Markup(self.req.args.get('body')) 
     514 
     515                # Display message list. 
     516                if new_author: 
     517                    self.req.hdf['discussion.author'] = wiki_to_oneliner( 
     518                      new_author, self.env) 
     519                if new_subject: 
     520                    self.req.hdf['discussion.subject'] = wiki_to_oneliner( 
     521                      new_subject, self.env) 
     522                if new_body: 
     523                    self.req.hdf['discussion.body'] = wiki_to_html(new_body, 
    393524                      self.env, self.req) 
    394525                self.req.hdf['discussion.messages'] = self.get_messages(topic['id']) 
     526 
    395527            elif mode == 'message-quote': 
    396528                self.req.perm.assert_permission('DISCUSSION_APPEND') 
     529 
     530                # Prepare old content. 
    397531                lines = message['body'].splitlines() 
    398532                for I in xrange(len(lines)): 
    399533                    lines[I] = '> %s' % (lines[I]) 
    400534                self.req.hdf['args.body'] = '\n'.join(lines) 
     535 
    401536            elif mode == 'message-post-add': 
    402537                self.req.perm.assert_permission('DISCUSSION_APPEND') 
    403                 author = Markup(self.req.args.get('author')) 
    404                 body = Markup(self.req.args.get('body')) 
     538 
     539                # Get form values. 
     540                new_author = Markup(self.req.args.get('author')) 
     541                new_body = Markup(self.req.args.get('body')) 
     542 
     543                # Add message. 
    405544                if message: 
    406545                    self.add_message(forum['id'], topic['id'], message['id'], 
    407                       author, body) 
    408                 else: 
    409                     self.add_message(forum['id'], topic['id'], '-1', author, body) 
     546                      new_author, new_body) 
     547                else: 
     548                    self.add_message(forum['id'], topic['id'], '-1', new_author, new_body) 
     549 
     550            elif mode == 'message-edit': 
     551                self.req.perm.assert_permission('DISCUSSION_APPEND') 
     552                if not is_moderator and (message['author'] != self.req.authname): 
     553                    raise PermissionError('Message edit') 
     554 
     555                # Prepare form values. 
     556                self.req.hdf['args.body'] = message['body'] 
     557 
     558            elif mode == 'message-post-edit': 
     559                self.req.perm.assert_permission('DISCUSSION_APPEND') 
     560                if not is_moderator and (message['author'] != self.req.authname): 
     561                    raise PermissionError('Message edit') 
     562 
     563                # Get form values. 
     564                new_body = Markup(self.req.args.get('body')) 
     565 
     566                # Edit message. 
     567                message['body'] = new_body 
     568                self.edit_message(message['id'], message['forum'], 
     569                  message['topic'], message['replyto'], new_body) 
     570 
    410571            elif mode == 'message-delete': 
    411572                self.req.perm.assert_permission('DISCUSSION_MODERATE') 
    412573                if not is_moderator: 
    413574                    raise PermissionError('Forum moderate') 
     575 
     576                # Delete message. 
    414577                self.delete_message(message['id']) 
    415578 
     
    494657        sql = "UPDATE forum_group SET name = %s, description = %s WHERE id = %s" 
    495658        self.log.debug(sql % (name, description, group)) 
    496         self.cursor.execute(sql, (name, description, group)) 
     659        self.cursor.execute(sql, (escape(name), escape(description), group)) 
    497660 
    498661    def edit_forum(self, forum, name, subject, description, moderators, group): 
     
    504667        self.log.debug(sql % (name, subject, description, moderators, 
    505668          group, forum)) 
    506         self.cursor.execute(sql, (name, subject, description, moderators, 
    507           group, forum)) 
     669        self.cursor.execute(sql, (escape(name), escape(subject), 
     670          escape(description), escape(moderators), group, forum)) 
     671 
     672    def edit_topic(self, topic, forum, subject, body): 
     673        sql = "UPDATE topic SET forum = %s, subject = %s, body = %s WHERE id" \ 
     674          " = %s" 
     675        self.log.debug(sql % (forum, subject, body, topic)) 
     676        self.cursor.execute(sql, (forum, escape(subject), escape(body), 
     677          topic)) 
     678 
     679    def edit_message(self, message, forum, topic, replyto, body): 
     680        sql = "UPDATE message SET forum = %s, topic = %s, replyto = %s, body" \ 
     681          " = %s WHERE id = %s" 
     682        self.log.debug(sql % (forum, topic, replyto, body, message)) 
     683        self.cursor.execute(sql, (forum, topic, replyto, escape(body), 
     684          message)) 
    508685 
    509686    # Get list functions 
     
    548725        for row in self.cursor: 
    549726            row = dict(zip(columns, row)) 
    550             #row['name'] = wiki_to_oneliner(row['name'], self.env) 
    551             #row['subject'] = wiki_to_oneliner(row['subject'], self.env) 
    552727            row['moderators'] = wiki_to_oneliner(row['moderators'], self.env) 
    553728            row['description'] = wiki_to_oneliner(row['description'], self.env) 
     
    630805        self.cursor.execute(sql, (escape(name), escape(description))) 
    631806 
    632  
    633807    def add_forum(self, name, author, subject, description, moderators, group): 
    634808        moderators = ' '.join(moderators) 
     
    656830          author, body)) 
    657831        self.cursor.execute(sql, (forum, topic, replyto, int(time.time()), 
    658           escape(author), escape(Markup(body)))) 
     832          escape(author), escape(body))) 
    659833 
    660834    # Delete items functions 
  • discussionplugin/0.9/tracdiscussion/core.py

    r1066 r1077  
    33from trac.web.chrome import INavigationContributor, ITemplateProvider 
    44from trac.web.main import IRequestHandler 
    5 from trac.perm import IPermissionRequestor, PermissionError 
     5from trac.perm import IPermissionRequestor 
    66import re 
    77 
  • discussionplugin/0.9/tracdiscussion/htdocs/css/discussion.css

    r1071 r1077  
    5151} 
    5252 
    53  
    5453/* Topic list */ 
    5554.topic-list td.id, .topic-list td.author, .topic-list td.lastreply, 
     
    6867{ 
    6968  margin: 2em; 
    70 
    71  
    72 .message-list .topic div.header 
    73 
     69  margin-bottom: 0em; 
    7470  border: 1px solid #d7d7d7; 
    7571} 
    7672 
    77 .message-list .topic div.subject 
     73.message-list div.topic div.subject 
    7874{ 
    7975  font-weight: bold; 
     
    8480} 
    8581 
    86 .message-list .header div.body 
     82.message-list div.topic > fieldset 
     83
     84  margin: 1em; 
     85
     86 
     87.message-list div.topic div.body 
    8788{ 
    8889  margin: 1em; 
     
    9091 
    9192/* Message list reply tree */ 
    92 .message-list .replies div.body 
     93.message-list div.replies div.body 
    9394{ 
    9495  margin: 0.2em; 
     
    9899{ 
    99100  display: block; 
    100   margin: 0px; 
     101  margin: 2em; 
     102  margin-top: 0em; 
    101103  padding: 0.25em; 
    102104  border-right: 1px solid #d7d7d7; 
     
    148150} 
    149151 
    150 .message-list .topic .replies div.body 
     152.message-list div.replies div.body 
    151153{ 
    152154  margin: 0em; 
     
    156158} 
    157159 
    158 .message-list .topic .replies .preview div.body 
     160.message-list div.replies li.preview div.body 
    159161{ 
    160162  border: 1px dashed #b00; 
  • discussionplugin/0.9/tracdiscussion/templates/forum-add.cs

    r1066 r1077  
    99    <div class="field"> 
    1010      <label for="name">Name:</label><br/> 
    11       <input type="text" name="name" value=""/><br/> 
     11      <input type="text" id="name" name="name" value=""/><br/> 
    1212    </div> 
    1313    <div class="field"> 
    1414      <label for="subject">Subject:</label><br/> 
    15       <input type="text" name="subject" value=""/><br/> 
     15      <input type="text" id="subject" name="subject" value=""/><br/> 
    1616    </div> 
    1717    <div class="field"> 
    1818      <label for="description">Description:</label><br/> 
    19       <input type="text" name="description" value=""/><br/> 
     19      <input type="text" id="description" name="description" value=""/><br/> 
    2020    </div> 
    2121    <div class="field"> 
    2222      <label for="moderators">Moderators:</label><br/> 
    2323      <?cs if:discussion.users.0 ?> 
    24         <select name="moderators" multiple="on"> 
     24        <select id="moderators" name="moderators" multiple="on"> 
    2525          <?cs each:user = discussion.users ?> 
    2626            <option value="<?cs var:user ?>"><?cs var:user ?></option> 
     
    2828        </select><br/> 
    2929      <?cs else ?> 
    30         <input type="text" name="moderators" value=""/><br/> 
     30        <input type="text" id="moderators" name="moderators" value=""/><br/> 
    3131      <?cs /if ?> 
    3232    </div> 
     
    3434      <div class="group"> 
    3535        <label for="group">Forum Group:</label><br/> 
    36         <select name="group"> 
     36        <select id="group" name="group"> 
    3737          <?cs each:group = discussion.groups ?> 
    3838            <option value="<?cs var:group.id ?>"><?cs var:group.name ?></option> 
     
    4141      </div> 
    4242    <?cs else ?> 
    43       <input type="hidden" name="group" value="0"/> 
     43      <input type="hidden" id="group" name="group" value="0"/> 
    4444    <?cs /if ?> 
    4545    <div class="buttons"> 
  • discussionplugin/0.9/tracdiscussion/templates/message-list.cs

    r1073 r1077  
    22  <li class="preview"> 
    33    <a name="preview"></a> 
     4    <div class="id"> 
     5        Message #?? 
     6    </div> 
    47    <div class="body"> 
    58      <?cs var:discussion.body ?> 
     
    1619<?cs /def ?> 
    1720 
    18 <?cs def:display_form() ?> 
     21<?cs def:display_reply_form() ?> 
    1922  <li class="reply"> 
    2023    <fieldset> 
     
    2730          <label for="author">Author:</label><br/> 
    2831          <?cs if:args.author ?> 
    29             <input type="text" name="author" value="<?cs var:args.author ?>"/><br/> 
     32            <input type="text" id="author" name="author" value="<?cs var:args.author ?>"/><br/> 
    3033          <?cs else ?> 
    31             <input type="text" name="author" value="<?cs var:discussion.authname ?>"/><br/> 
     34            <input type="text" id="author" name="author" value="<?cs var:discussion.authname ?>"/><br/> 
    3235          <?cs /if ?> 
    3336        </div> 
    3437        <div class="field"> 
    3538          <label for="body">Body:</label><br/> 
    36           <textarea name="body" class="wikitext" rows="10" cols="78"><?cs alt:args.body ?>Enter your message here...<?cs /alt ?></textarea> 
     39          <textarea id="body" name="body" class="wikitext" rows="10" cols="78"><?cs alt:args.body ?>Enter your message here...<?cs /alt ?></textarea> 
    3740        </div> 
    3841        <div class="buttons"> 
     
    4851    </fieldset> 
    4952  </li> 
     53<?cs /def ?> 
     54 
     55<?cs def:display_edit_form() ?> 
     56  <fieldset> 
     57    <a name="reply"></a> 
     58    <legend> 
     59      Edit: 
     60    </legend> 
     61    <form method="get" action="<?cs var:discussion.href ?>#preview"> 
     62      <?cs if:!args.message ?> 
     63        <div class="field"> 
     64          <label for="subject">Subject:</label><br/> 
     65          <input type="text" id="subject" name="subject" value="<?cs var:args.subject ?>"/><br/> 
     66        </div> 
     67      <?cs /if ?> 
     68      <div class="field"> 
     69        <label for="body">Body:</label><br/> 
     70        <textarea id="body" name="body" class="wikitext" rows="10" cols="78"><?cs var:args.body ?></textarea> 
     71      </div> 
     72      <div class="buttons"> 
     73        <input type="submit" name="preview" value="Preview"/> 
     74        <input type="submit" name="submit" value="Edit"/> 
     75        <input type="button" name="cancel" value="Cancel" onclick="location.href = '<?cs var:discussion.href ?>#<?cs var:args.message ?>'"/> 
     76      </div> 
     77      <?cs if:args.message ?> 
     78        <input type="hidden" name="message" value="<?cs var:args.message ?>"/> 
     79      <?cs /if ?> 
     80      <input type="hidden" name="discussion_action" value="post-edit"/> 
     81    </form> 
     82  </fieldset> 
    5083<?cs /def ?> 
    5184 
     
    5891      </div> 
    5992      <div class="body"> 
    60         <?cs var:message.body ?> 
     93        <?cs if:(args.message == message.id) && args.preview ?> 
     94          <?cs var:discussion.body ?> 
     95        <?cs else?> 
     96          <?cs var:message.body ?> 
     97        <?cs /if ?> 
    6198      </div> 
    6299      <div class="controls"> 
     
    64101          <a href="<?cs var:discussion.href ?>?discussion_action=add;message=<?cs var:message.id ?>#reply">Reply</a> 
    65102          <a href="<?cs var:discussion.href ?>?discussion_action=quote;message=<?cs var:message.id ?>#reply">Quote</a> 
     103          <?cs if:discussion.is_moderator || (message.author == discussion.authname) ?> 
     104            <a href="<?cs var:discussion.href ?>?discussion_action=edit;message=<?cs var:message.id ?>#reply">Edit</a> 
     105          <?cs /if ?> 
    66106        <?cs /if ?> 
    67107        <?cs if:trac.acl.DISCUSSION_MODERATE && discussion.is_moderator ?> 
     
    77117        </div> 
    78118      </div> 
     119      <?cs if:(args.message == message.id) && !args.submit && ((args.discussion_action == 'edit') || (args.discussion_action == 'post-edit')) ?> 
     120        <?cs call:display_edit_form() ?> 
     121      <?cs /if ?> 
    79122    </li> 
    80     <?cs if:discussion.messages.0.id || args.discussion_action && !args.submit && (args.discussion_action != "delete") ?> 
     123    <?cs if:message.replies.0.id || args.discussion_action && (args.discussion_action != 'delete') && (args.discussion_action != 'edit') && (args.discussion_action != 'post-edit') ?> 
    81124      <ul> 
    82         <?cs call:display_topic(message.replies) ?> 
    83         <?cs if:args.discussion_action && args.preview && args.message == message.id ?> 
    84            <?cs call:display_preview() ?> 
    85         <?cs /if ?> 
    86         <?cs if:args.discussion_action && !args.submit && args.message == message.id ?> 
    87           <?cs call:display_form() ?> 
     125        <?cs if:message.replies.0.id ?> 
     126          <?cs call:display_topic(message.replies) ?> 
     127        <?cs /if ?> 
     128        <?cs if:(args.message == message.id) && !args.submit && args.discussion_action && (args.discussion_action != "delete") && (args.discussion_action != 'edit') && (args.discussion_action != 'post-edit') ?> 
     129          <?cs if:args.preview ?> 
     130            <?cs call:display_preview() ?> 
     131          <?cs /if ?> 
     132          <?cs call:display_reply_form() ?> 
    88133        <?cs /if ?> 
    89134      </ul> 
     
    110155      <div class="header"> 
    111156        <div class="subject"> 
    112           <?cs var:discussion.topic.subject ?> 
    113         </div> 
    114         <div class="body"> 
     157          <?cs if:!args.message && args.preview ?> 
     158            <?cs var:discussion.subject ?> 
     159          <?cs else?> 
     160            <?cs var:discussion.topic.subject ?> 
     161          <?cs /if ?> 
     162        </div> 
     163      </div> 
     164      <div class="body"> 
     165        <?cs if:!args.message && args.preview ?> 
     166          <?cs var:discussion.body ?> 
     167        <?cs else?> 
    115168          <?cs var:discussion.topic.body ?> 
    116         </div> 
    117         <div class="controls"> 
    118           <?cs if:trac.acl.DISCUSSION_APPEND ?> 
    119             <a href="<?cs var:discussion.href ?>?discussion_action=add;#reply">Reply</a> 
    120             <a href="<?cs var:discussion.href ?>?discussion_action=quote;#reply">Quote</a> 
    121           <?cs /if ?> 
    122         </div> 
    123         <div class="footer"> 
    124           <div class="author"> 
    125             <?cs var:discussion.topic.author ?> 
    126           </div> 
    127           <div class="time"> 
    128             <?cs var:discussion.topic.time ?> 
    129           </div> 
    130         </div> 
    131       </div> 
    132       <?cs if:discussion.messages.0.id || args.discussion_action && !args.submit && (args.discussion_action != "delete") ?> 
    133         <div class="replies"> 
    134           <ul> 
     169        <?cs /if ?> 
     170      </div> 
     171      <div class="controls"> 
     172        <?cs if:trac.acl.DISCUSSION_APPEND ?> 
     173          <a href="<?cs var:discussion.href ?>?discussion_action=add;#reply">Reply</a> 
     174          <a href="<?cs var:discussion.href ?>?discussion_action=quote;#reply">Quote</a> 
     175          <?cs if:discussion.is_moderator || (discussion.topic.author == discussion.authname) ?> 
     176            <a href="<?cs var:discussion.href ?>?discussion_action=edit;#reply">Edit</a> 
     177          <?cs /if ?> 
     178        <?cs /if ?> 
     179      </div> 
     180      <div class="footer"> 
     181        <div class="author"> 
     182          <?cs var:discussion.topic.author ?> 
     183        </div> 
     184        <div class="time"> 
     185          <?cs var:discussion.topic.time ?> 
     186        </div> 
     187      </div> 
     188      <?cs if:!args.message && !args.submit && ((args.discussion_action == 'edit') || (args.discussion_action == 'post-edit')) ?> 
     189        <?cs call:display_edit_form() ?> 
     190      <?cs /if ?> 
     191    </div> 
     192    <?cs if:discussion.messages.0.id || args.discussion_action && (args.discussion_action != "delete") && (args.discussion_action != 'edit') && (args.discussion_action != 'post-edit') ?> 
     193      <div class="replies"> 
     194        <ul> 
     195          <?cs if:discussion.messages.0.id ?> 
    135196            <?cs call:display_topic(discussion.messages) ?> 
    136             <?cs if:args.discussion_action && args.preview && !args.message ?> 
     197          <?cs /if ?> 
     198          <?cs if:!args.message && !args.submit && args.discussion_action && (args.discussion_action != "delete") && (args.discussion_action != 'edit') && (args.discussion_action != 'post-edit') ?> 
     199            <?cs if:args.preview ?> 
    137200              <?cs call:display_preview() ?> 
    138201            <?cs /if ?> 
    139             <?cs if:args.discussion_action && !args.submit && !args.message ?> 
    140               <?cs call:display_form() ?> 
    141             <?cs /if ?> 
    142           </ul> 
    143         </div> 
    144       <?cs /if ?> 
    145     </div> 
    146    <?cs else?> 
    147      <span>No discussion for this page created.</span> 
    148    <?cs /if ?> 
     202            <?cs call:display_reply_form() ?> 
     203          <?cs /if ?> 
     204        </ul> 
     205      </div> 
     206    <?cs /if ?> 
     207  <?cs else?> 
     208    <span>No discussion for this page created.</span> 
     209  <?cs /if ?> 
    149210<?cs else ?> 
    150211  <span>You have no rights to see this discussion.</span> 
     
    158219    </form> 
    159220    <?cs if:!discussion.no_navigation ?> 
    160       <form method="get" action="<?cs var:discussion.href ?>/<?cs var:discussion.forum.id ?>/<?cs var:discussion.topic.id ?>"> 
     221      <form method="get" action="<?cs var:discussion.href ?>"> 
    161222        <input type="submit" name="movetopic" value="Move Topic"/> 
    162223        <input type="hidden" name="discussion_action" value="move"/>