Changeset 1466

Show
Ignore:
Timestamp:
03/06/08 13:35:03 (2 years ago)
Author:
JensDiemer
Message:
  • page_archiv:
    • add .../db/page_archiv.py for shared function related to the page archiv.
    • change the model and add a comment field
  • page_admin:
    • Use a normal newforms and not the ugly formfield_callback way.
    • in "preview" the markup editor changed ('current_markup' variable)


TODO: the page_admin needs a unitest!

Location:
trunk/pylucid
Files:
2 added
7 modified

Legend:

Unmodified
Added
Removed
  • trunk/pylucid/media/PyLucid/internal_page/page_admin/edit_page.css

    r1449 r1466  
    2424    padding: 4px; 
    2525} 
    26 #edit_page_form label { 
     26/* -------------------------------------------------------------------------- */ 
     27#input_fields label, #input_fields input, #input_fields select { 
     28    /* make all fields except the textarea a little bit smaller */ 
     29    font-size: 0.8em; 
     30} 
     31#input_fields .field_help_text { 
     32    font-size:0.7em; 
     33} 
     34#input_fields label { 
    2735    float: left; 
    2836    padding-right: 4px; 
    2937    text-align: right; 
    30     width: 6.5em; 
     38    width: 9em; 
    3139} 
    32 #edit_page_form input, #edit_page_form select { 
    33     width: 30%; 
    34 } 
    35 #edit_page_form .field_help_text { 
    36     font-size:0.7em; 
     40#input_fields input, #input_fields select { 
     41    width: 35%; 
    3742} 
    3843 
    39 #edit_page_form .content label, #edit_page_form .content .field_help_text { 
     44#input_fields .content label, #input_fields .content .field_help_text { 
    4045    /* hide label and help_text around the textarea */ 
    4146    display:none; 
    4247} 
    43 #edit_page_form .keywords input, #edit_page_form .description input { 
    44     /* make keywords and description input bigger */ 
     48#input_fields .bigger { 
     49    /* make some text input fields bigger e.g. keywords,description */ 
    4550    width: 75%; 
    4651} 
    47 #edit_page_form .keywords .field_help_text, #edit_page_form .description .field_help_text { 
     52#input_fields .edit_comment .field_help_text, 
     53#input_fields .keywords .field_help_text, 
     54#input_fields .description .field_help_text { 
    4855    /* setup the help text for keywords and description */ 
     56    /* put the help text for bigger input field in the second line */ 
    4957    display: block; 
    50     padding-left: 10em; 
     58    padding-left: 14em; 
    5159} 
    52 #edit_page_form textarea, hr.seperator, #action_buttons { 
     60#input_fields textarea, hr.seperator, #action_buttons { 
    5361    /* make the space between the action buttons and the text area smaller */ 
    5462    margin: 0; 
  • trunk/pylucid/media/PyLucid/internal_page/page_admin/edit_page.html

    r1449 r1466  
    1  
    21{% if preview_content %} 
    32<fieldset id="page_preview"> 
     
    3534        </a> 
    3635        </li> 
    37         {% if not tinymce %} 
     36        {% if not use_tinymce %} 
    3837        <li> 
    3938        <button type="button" class="resize_buttons" onclick="JavaScript:resize_big(); return false" title="{% trans 'makes the textarea bigger' %}"> 
     
    4746    </ul> 
    4847    <hr class="seperator" /> 
    49     <ul> 
     48    <ul id="input_fields"> 
    5049        {% for field in edit_page_form %} 
    5150            <li title="{{ field.help_text }}" class="{{ field.html_name }}"> 
     
    5958</form> 
    6059</fieldset> 
    61 {% if tinymce %}{{ tinymce }}{% endif %} 
  • trunk/pylucid/media/PyLucid/internal_page/page_admin/edit_page.js

    r1449 r1466  
    1 function init_tinyMCE() { 
    2     tinyMCE.init({ 
    3         apply_source_formatting : true, 
    4         mode : "textareas", 
    5         plugins : "table,fullscreen", 
    6         theme_advanced_buttons3_add : "tablecontrols,fullscreen", 
    7         height : "480", 
    8         auto_focus : "mce_editor_0", 
    9         theme : "advanced", 
    10     }); 
    11 } 
    121 
    132page_content_changed = 0; 
  • trunk/pylucid/PyLucid/install/install.py

    r1406 r1466  
    3030    # Drop this tables before syncdb: 
    3131    DROP_TABLES = ( 
    32         "PyLucid_preference", "PyLucid_js_logindata", "PyLucid_markup" 
     32        "PyLucid_pagearchiv", 
    3333    ) 
    3434 
     
    3939 
    4040    def _drop_tables(self): 
     41        """ 
     42        This is only important for development, if we create a new model and 
     43        change it. 
     44        Should be not used in productive environment! 
     45        """ 
    4146        print 
    4247        print "drop tables:" 
     
    7681def syncdb(request): 
    7782    """ 
    78     1. install Db tables (syncdb, Note: preferences, JS_LoginData, markup lost!) 
     83    1. install Db tables (syncdb) 
    7984    """ 
    8085    return Sync_DB(request).start_view() 
  • trunk/pylucid/PyLucid/models.py

    r1464 r1466  
    379379    ) 
    380380 
    381     original = models.ForeignKey("Page") 
     381    page = models.ForeignKey("Page", 
     382        help_text="relationship to the original page entry" 
     383    ) 
     384    edit_comment = models.CharField( 
     385        blank=True, max_length=255, 
     386        help_text="The reason for editing." 
     387    ) 
    382388 
    383389    class Admin: 
    384390        list_display = ( 
    385             "id", "shortcut", "name", "title", "description", 
    386             "lastupdatetime", "lastupdateby" 
     391            "id", "page", "edit_comment", "shortcut", "name", "title", 
     392            "description", "lastupdatetime", "lastupdateby" 
    387393        ) 
    388394 
  • trunk/pylucid/PyLucid/plugins_internal/page_admin/page_admin.py

    r1464 r1466  
    3737 
    3838from django.conf import settings 
    39 from PyLucid.models import Page, Plugin, PageArchiv 
     39from PyLucid.models import Page, Plugin, PageArchiv, MARKUPS 
    4040from PyLucid.db.page import flat_tree_list, get_sitemap_tree 
     41from PyLucid.db.page_archiv import archive_page 
    4142from PyLucid.system.BasePlugin import PyLucidBasePlugin 
    4243from PyLucid.system.detect_page import get_default_page_id 
     
    4546from PyLucid.plugins_internal.page_style.page_style import replace_add_data 
    4647 
    47 #______________________________________________________________________________ 
    48 # Escape TextFields 
    49 # http://groups.google.com/group/django-users/browse_thread/thread/d4d9a8c5e7019762 
    50  
    51 class EscapedTextarea(forms.Textarea): 
    52     def render(self, name, value, attrs=None): 
    53         """ 
    54         -Escape/Quote the django template tags chars "{" and "}" to the 
    55             HTML character entity. 
    56         -Override the default textarea attributes and make it bigger 
    57             Node: The cols size are setup with CSS and "width:100%;" 
    58         """ 
    59         attrs = {'rows': '15'} 
    60         content = super(EscapedTextarea, self).render(name, value, attrs) 
    61 #        content = content.replace("{", "&#x7B;").replace("}", "&#x7D;") 
    62 #        content = mark_safe(content) # turn djngo auto-escaping off 
    63         return content 
    64  
    65 class EscapedTextField(forms.Field): 
    66     "Change the textarea widget" 
    67     widget = EscapedTextarea 
    68  
    69 class ParentMultipleChoiceField(forms.ChoiceField): 
    70     """ 
    71     Change the "parent" choice field with a verbose name tree list. 
    72     TODO: We must ask the database a second time :( 
    73     """ 
    74     def __init__(self, *args, **kwargs): 
    75         super(ParentMultipleChoiceField, self).__init__(*args, **kwargs) 
    76  
    77         page_list = flat_tree_list() 
    78         choices = [(None, "---[root]---")] 
    79         for page in page_list: 
    80             choices.append((page["id"], page["level_name"])) 
    81  
    82         self.choices = choices 
    83  
    84     def clean(self, value): 
    85         """ 
    86         TODO: We should check if the parent_id is ok and not make a wrong 
    87         id-parent-loop. Now, this is checkt in PyLucid.models.Page.save() 
    88         """ 
    89         if value == "None": 
     48 
     49class ParentChoiceField(forms.IntegerField): 
     50    def clean(self, parent_id): 
     51        """ 
     52        returns the parent page instance. 
     53        Note: 
     54            In PyLucid.models.Page.save() it would be checkt if the selected 
     55            parent page is logical valid. Here we check only, if the page with 
     56            the given ID exists. 
     57        """ 
     58        # let convert the string into a integer: 
     59        parent_id = super(ParentChoiceField, self).clean(parent_id) 
     60        assert isinstance(parent_id, int) 
     61 
     62        if parent_id == 0: 
    9063            # assigned to the tree root. 
    9164            return None 
     65 
    9266        try: 
    93             #value = "test int() error" 
    94             parent_id = int(value) 
    9567            #parent_id = 999999999 # Not exists test 
    96             return Page.objects.get(id=parent_id) 
     68            page = Page.objects.get(id=parent_id) 
     69            return page 
    9770        except Exception, msg: 
    9871            raise ValidationError(_(u"Wrong parent POST data: %s" % msg)) 
    9972 
    100 def formfield_callback(field, **kwargs): 
     73 
     74def get_parent_choices(): 
    10175    """ 
    102     -change the 'content' text fields to our own EscapedTextField 
    103     -change the 'parent' field to a "verbose name tree" choice field. 
     76    generate a verbose page name tree for the parent choice field. 
    10477    """ 
    105     if field.name == "content": 
    106         # replace the content field 
    107         return EscapedTextField(**kwargs) 
    108     elif field.name == "parent": 
    109         # replace the parent field 
    110         return ParentMultipleChoiceField(**kwargs) 
    111     else: 
    112         # Do nothing with the other fields: 
    113         return field.formfield(**kwargs) 
     78    page_list = flat_tree_list() 
     79    choices = [(0, "---[root]---")] 
     80    for page in page_list: 
     81        choices.append((page["id"], page["level_name"])) 
     82    return choices 
     83 
     84class EditPageForm(forms.Form): 
     85    """ 
     86    Form for editing a cms page. 
     87    """ 
     88    edit_comment = forms.CharField( 
     89        max_length=255, required=False, 
     90        help_text=_("The reason for editing."), 
     91        widget=forms.TextInput(attrs={'class':'bigger'}), 
     92    ) 
     93 
     94    content = forms.CharField( 
     95        widget=forms.Textarea(attrs={'rows': '15'}), 
     96    ) 
     97 
     98    parent = ParentChoiceField( 
     99        widget=forms.Select(choices=get_parent_choices()), 
     100        # FIXME: How to set invalid_choice here? 
     101        help_text="the higher-ranking father page", 
     102    ) 
     103 
     104    name = forms.CharField( 
     105        max_length=255, help_text=_("A short page name"), 
     106    ) 
     107    title = forms.CharField( 
     108        max_length=255, required=False, help_text=_("A long page title"), 
     109    ) 
     110    markup = forms.IntegerField( 
     111        widget=forms.Select(choices=MARKUPS), 
     112        help_text=_("the used markup language for this page"), 
     113    ) 
     114 
     115    keywords = forms.CharField( 
     116        max_length=255, required=False, 
     117        help_text=_("Keywords for the html header. (separated by commas)"), 
     118        widget=forms.TextInput(attrs={'class':'bigger'}), 
     119    ) 
     120    description = forms.CharField( 
     121        max_length=255, required=False, 
     122        help_text=_("Short description of the contents. (for the html header)"), 
     123        widget=forms.TextInput(attrs={'class':'bigger'}), 
     124    ) 
    114125 
    115126#______________________________________________________________________________ 
     
    170181        self.context["PAGE"] = page_instance 
    171182 
     183    def _save_edited_page(self, page_instance, html_form): 
     184        """ 
     185        Save a edited page into the database. 
     186 
     187        if a old page was edited: 
     188            -Archive the old page data 
     189        if a new page was created: 
     190            -return the new page content for rendering 
     191        """ 
     192        if page_instance.id == self.current_page.id: 
     193            # A existing page was edited 
     194            edit_comment = html_form.cleaned_data["edit_comment"] 
     195            # achive the old page data: 
     196            archive_page(self.current_page, edit_comment) 
     197            self.page_msg(_("Old page data archived.")) 
     198 
     199        # Transfer the form values into the page instance 
     200        for key, value in html_form.cleaned_data.iteritems(): 
     201            if key != "edit_comment": # The comment is only for the page archiv 
     202                setattr(page_instance, key, value) 
     203 
     204        try: 
     205            page_instance.save() 
     206        except Exception, msg: 
     207            self.page_msg("Can't save the page data:", msg) 
     208            return 
     209 
     210        # Delete the old page data cache: 
     211        self._delete_cache(page_instance) 
     212 
     213        if page_instance.id == self.current_page.id: 
     214            # Normal page edit 
     215            self.page_msg(_("Page data updated.")) 
     216        else: 
     217            self.page_msg(_("The new page created.")) 
     218 
     219            # refresh the current page data: 
     220            self._refresh_curent_page(page_instance) 
     221 
     222            # return the new page content for rendering 
     223            return self.current_page.content 
     224 
    172225 
    173226    def edit_page(self, edit_page_id=None, new_page_instance=None): 
     
    197250        } 
    198251 
    199         # FIXME: Quick hack 'escape' Template String. 
    200         # With the formfield_callback we switched the widget render method 
    201         # and escape/quote the characters "{" and "}" so they are invisible to 
    202         # the django template engine and the tag (not the result of the tag) is 
    203         # editable ;) 
    204         # http://www.djangoproject.com/documentation/newforms/#overriding-the-default-field-types 
    205         # -With the formfield_callback we change the parent field, too. 
    206         PageForm = forms.models.form_for_instance( 
    207             page_instance, fields=( 
    208                 "content", "parent", 
    209                 "name", "title", 
    210                 "keywords", "description", "markup", 
    211             ), 
    212             formfield_callback=formfield_callback 
    213         ) 
    214  
    215         if self.request.method == 'POST': 
    216 #            self.page_msg(self.request.POST) 
    217             html_form = PageForm(self.request.POST) 
     252        # The markup is a little dynamicly. It should always be used the current 
     253        # markup editor (html with or without TinyMCE) e.g. The user change the 
     254        # markup and used the "preview" fuction. 
     255        current_markup = page_instance.markup 
     256 
     257        if self.request.method != 'POST': 
     258            parent = getattr(page_instance.parent, "id", 0) # Root is None 
     259 
     260            html_form = EditPageForm({ 
     261                "content": page_instance.content, 
     262                "parent": parent, 
     263                "name": page_instance.name, 
     264                "title": page_instance.title, 
     265                "markup": current_markup, 
     266                "keywords": page_instance.keywords, 
     267                "description": page_instance.description 
     268            }) 
     269        else: # POST 
     270            #self.page_msg(self.request.POST) 
     271            html_form = EditPageForm(self.request.POST) 
    218272            if html_form.is_valid(): 
    219273                if "preview" in self.request.POST: 
     
    226280                    content = render_string_template(content, self.context) 
    227281                    context["preview_content"] = content 
     282 
     283                    # Use the current selected markup 
     284                    current_markup = html_form.cleaned_data["markup"] 
     285 
    228286                elif "save" in self.request.POST: 
    229                     # FIXME: How to transfer the attributes easier? 
    230                     old_page = PageArchiv( 
    231                         content           = self.current_page.content, 
    232                         parent            = self.current_page.parent, 
    233                         position          = self.current_page.position, 
    234                         name              = self.current_page.name, 
    235                         shortcut          = self.current_page.shortcut, 
    236                         title             = self.current_page.title, 
    237                         template          = self.current_page.template, 
    238                         style             = self.current_page.style, 
    239                         markup            = self.current_page.markup, 
    240                         keywords          = self.current_page.keywords, 
    241                         description       = self.current_page.description, 
    242                         createtime        = self.current_page.createtime, 
    243                         lastupdatetime    = self.current_page.lastupdatetime, 
    244                         createby          = self.current_page.createby, 
    245                         lastupdateby      = self.current_page.lastupdateby, 
    246                         showlinks         = self.current_page.showlinks, 
    247                         permitViewPublic  = self.current_page.permitViewPublic, 
    248                         permitViewGroup   = self.current_page.permitViewGroup, 
    249                         permitEditGroup   = self.current_page.permitEditGroup, 
    250  
    251                         original = self.current_page 
    252                     ) 
    253                     old_page.save() 
    254                     self.page_msg(_("Old page data archived.")) 
    255  
    256                     old_content = self.current_page.content 
    257                     # Save the new page data into the database: 
    258                     try: 
    259                         html_form.save() 
    260                     except Exception, msg: 
    261                         self.page_msg("Can't save the page data:", msg) 
    262                     else: 
    263                         # Delete the old page data cache: 
    264                         self._delete_cache(page_instance) 
    265  
    266                         if page_instance.id == self.current_page.id: 
    267                             # Normal page edit 
    268                             self.page_msg(_("Page data updated.")) 
    269                             return 
    270                         else: 
    271                             self.page_msg(_("The new page created.")) 
    272  
    273                             # refresh the current page data: 
    274                             self._refresh_curent_page(page_instance) 
    275  
    276                             # return the new page content for rendering 
    277                             return self.current_page.content 
     287                    # Save the new page data. returns a new page instance 
     288                    return self._save_edited_page(page_instance, html_form) 
    278289                else: 
    279290                    self.page_msg.red("Form error!") 
    280         else: 
    281             html_form = PageForm() 
    282291 
    283292        context["edit_page_form"] = html_form 
     
    297306        context["url_abort"] = url_abort 
    298307 
    299  
    300         if page_instance.markup == 1: 
     308        if current_markup == 1: 
    301309            # markup with id=1 is html + TinyMCE JS Editor 
    302             media_url = posixpath.join( 
     310            context["use_tinymce"] = True 
     311 
     312            # url to e.g. /media/PyLucid/tiny_mce/tiny_mce.js 
     313            tiny_mce_url = posixpath.join( 
    303314                settings.MEDIA_URL, settings.PYLUCID_MEDIA_DIR, 
     315                "tiny_mce", "tiny_mce.js" 
    304316            ) 
    305             js_data = ( 
    306                 '<script language="javascript" type="text/javascript"' 
    307                 ' src="%stiny_mce/tiny_mce.js"></script>\n' 
    308                 '<script language="javascript" type="text/javascript">\n' 
    309                 '    init_tinyMCE();\n' 
    310                 '</script>\n' 
    311             ) % media_url 
    312             context["tinymce"] = mark_safe(js_data) 
     317            # url to e.g. .../internal_page/page_admin/edit_page_tinymce.js 
     318            use_tiny_mce_url = self.internal_page.get_url( 
     319                "edit_page_tinymce", slug="js" 
     320            ) 
     321            # Add external media files 
     322            for url in (tiny_mce_url, use_tiny_mce_url): 
     323                # Add tiny_mce.js to 
     324                self.context["js_data"].append({ 
     325                    "plugin_name": self.plugin_name, 
     326                    "url": url, 
     327                }) 
    313328 
    314329        self._render_template("edit_page", context)#, debug=True) 
     
    348363        # make a new page skeleton object: 
    349364        new_page = Page( 
    350             name             = "New Page", 
     365            name             = "New page", 
    351366            shortcut         = "NewPage", 
     367            content          = "New page.", 
    352368            template         = parent.template, 
    353369            style            = parent.style, 
  • trunk/pylucid/PyLucid/system/internal_page.py

    r1459 r1466  
    113113                return u"" 
    114114            else: 
    115                 raise InternalPageNotFound() 
     115                msg = "Internal page '%s' not found in %s or %s" % ( 
     116                    internal_page_name, self.custom_plugin_root, 
     117                    self.default_plugin_root 
     118                ) 
     119                raise InternalPageNotFound(msg) 
    116120 
    117121        f = file(file_path, "r")