Changeset 4250 for TI05-delivery


Ignore:
Timestamp:
30/09/08 12:23:51 (11 years ago)
Author:
cbyrom
Message:

Add function to allow adding/editing online references + fix handling of
these so they are better displayed in view mode + allow use of fully
resolved term url - i.e. with version included + add 'remove' function
to author + online ref inputs + tidy up controller logic, creating new
method to set up data model before processing + adjust control flow - to
do a redirect following a save to ensure the page is set up afresh.

Location:
TI05-delivery/ows_framework/trunk/ows_server/ows_server
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • TI05-delivery/ows_framework/trunk/ows_server/ows_server/config/routing.py

    r4237 r4250  
    3636    map.connect('editAtom/:uri/:saveData', controller = 'editatom', action='edit') 
    3737    map.connect('editAtom/:uri', controller = 'editatom', action='edit') 
    38     map.connect('saveAtom', controller = 'editatom', action='saveAtom') 
     38    map.connect('saveAtom/:uri/:saveLevel', controller = 'editatom', \ 
     39                action='saveAtom', saveLevel='0') 
    3940    map.connect('createAtom/:saveData', controller = 'editatom', action='create') 
    4041    map.connect('createAtom', controller = 'editatom', action='create') 
  • TI05-delivery/ows_framework/trunk/ows_server/ows_server/controllers/editatom.py

    r4244 r4250  
    6464     
    6565    @validate(schema=AtomFormSchema(), form='saveAtom') 
    66     def saveAtom(self, **data): 
     66    def saveAtom(self, uri, saveLevel=0): 
    6767        ''' 
    6868        Save the atom contents - NB, validation is done by method decoration 
     
    7171        ''' 
    7272        logging.info("Saving input atom data") 
    73         logging.debug(request.params) 
    74          
    75         #c.errors = {} 
    76         #try: 
    77         #    logging.info("Retrieving and validating data from submitted page") 
    78         #    for i in data: 
    79         #        logging.debug("key: %s, val: %s" %(i, data[i])) 
    80         #    d = data.get('form_result') 
    81         #    logging.debug(d) 
    82             #validData = form.to_python(d) 
    83             #logging.info("Got data...") 
    84             #logging.info(validData) 
    85             #if validData: 
    86             #    link = Atom(**validData) 
    87         #    logging.info("Data retrieved successfully") 
    88             #self.data[link.id] = link 
    89             #raise cherrypy.HTTPRedirect('/') 
    90         #except Invalid, e: 
    91         #    logging.info("Errors occured") 
    92         #    logging.debug(e) 
    93         #    c.errors = e.unpack_errors() 
    94              
    95          
    96         templateType = "genshi" 
    97         renderTemplate = 'atom_editor' 
    98  
    99         #data = {'username':'gggggggggg'} 
    100         #filler = HTMLFormFiller(data=data)  
    101         #stream = HTML(render(templateType, renderTemplate)) | filler 
    102         #return stream.render(method='xhtml')  
    103             #return Response(HTMLFormFiller(data=data)) 
    104         return render(templateType, renderTemplate) 
     73        c.errors = {} 
     74        try: 
     75            self.prepareDataModel(uri) 
     76        except SystemError, e: 
     77            logging.error(e.message) 
     78            return render('error') 
     79         
     80         
     81        inputs = request.params 
     82        logging.debug("inputs:\n%s" %inputs) 
     83 
     84        authors = self.extractAuthorDetails(inputs) 
     85        if authors: 
     86            c.atom.addAuthors(authors) 
     87 
     88        onlineRefs = self.extractOnlineReferenceDetails(inputs) 
     89        if onlineRefs: 
     90            c.atom.relatedLinks = onlineRefs 
     91 
     92        if inputs.get('subtype'): 
     93            inputs['subtype'] = self.getLatestTermURLFromDropDownInput( \ 
     94                    inputs.get('subtype')) 
     95 
     96        self.saveAtomToExist(c.atom) 
     97                     
     98        # if we're dealing with an expandable text input, re-render this now 
     99        if int(saveLevel) > 1: 
     100            logging.debug("Doing a partial re-render") 
     101            c.key=request.params['key'] 
     102            c.default=request.params[c.key] 
     103            logging.debug(c.key) 
     104            logging.debug(c.default) 
     105 
     106            c.blkfrag=1 
     107            return render("genshi", 'utils', fragment=True) 
     108 
     109        # now do redirection - NB, this ensures that current atom contents are 
     110        # reloaded and displayed 
     111        h.redirect_to(controller = 'editatom', action='edit', \ 
     112                        uri = c.atom.ndgURI) 
     113 
     114 
     115    def prepareDataModel(self, uri): 
     116        ''' 
     117        Set up the underlying atom data model - loading the bulk from eXist 
     118        then updating any input fields appropriately  
     119        ''' 
     120        logging.info("Preparing underlying data model") 
     121        status=self.__setup(uri=uri) 
     122        if status: 
     123            c.xml='<p>%s</p>'%status  
     124            response.status_code = 400 
     125            raise SystemError('Problem experienced setting up data model') 
     126 
     127        logging.info("Retrieving document to edit") 
     128        # NB, don't use the cache as docs are likely to change 
     129        # quite a lot during editing; ensure you've always got  
     130        # the latest updates loaded 
     131        status,x = interface.GetXML(uri, useCache=False) 
     132 
     133        if not status: 
     134            code=400 
     135            if x.startswith('<p> Access Denied'): 
     136                code=401 
     137 
     138            c.xml='%s'%x 
     139            response.status_code = code 
     140            raise SystemError('Problem experienced retrieving atom doc from eXist') 
     141 
     142        # NB, passing in the inputs will overwrite any original values with the 
     143        # user input ones 
     144        inputs = request.params 
     145        c.atom = Atom(xmlString=str(x), ndgObject = self.ndgObject, **dict(inputs)) 
     146        logging.debug("Input params, '%s'" %inputs) 
     147        logging.debug("INPUTS: %s" %self.inputs) 
     148         
     149        logging.info("Data model set up") 
    105150 
    106151     
     
    112157        logging.info("Setting up atom edit template") 
    113158        c.errors = {} 
    114         status=self.__setup(uri=uri) 
    115         if status: 
    116             c.xml='<p>%s</p>'%status  
    117             response.status_code = 400 
     159        try: 
     160            self.prepareDataModel(uri) 
     161        except SystemError, e: 
     162            logging.error(e.message) 
    118163            return render('error') 
    119164 
    120         logging.info("Retrieving document to edit") 
    121         # NB, don't use the cache as docs are likely to change 
    122         # quite a lot during editing; ensure you've always got  
    123         # the latest updates loaded 
    124         status,x=interface.GetXML(uri, useCache=False) 
    125  
    126         if not status: 
    127             code=400 
    128             if x.startswith('<p> Access Denied'): 
    129                 code=401 
    130  
    131             c.xml='%s'%x 
    132             response.status_code = code 
    133             return render('error') 
    134  
    135165        c.title='Editing [%s]'%self.ndgObject 
    136166         
    137         c.saveLink = h.url_for(controller='editatom',action='edit', saveData='1') 
     167        c.saveLink = h.url_for(controller='editatom',action='saveAtom', \ 
     168                               saveLevel='1',  uri = c.atom.ndgURI) 
    138169        c.saveLink2 = h.url_for(controller='editatom',action='edit', saveData='2') 
    139         inputs = request.params 
    140         logging.debug("Input params, '%s'" %inputs) 
    141  
    142         # NB, passing in the inputs will overwrite any original values with the 
    143         # user input ones 
    144         c.atom = Atom(xmlString=str(x), ndgObject = self.ndgObject, **dict(inputs)) 
     170 
    145171 
    146172        c.subTypes = self.__getDropdown(VTD().getValidSubTypes(c.atom.atomTypeID), \ 
    147173                                        selected=c.atom.subtype) 
    148  
    149         if saveData: 
    150             logging.info("Saving atom data") 
    151             authors = self.extractAuthorDetails(inputs) 
    152             if authors: 
    153                 c.atom.addAuthors(authors) 
    154  
    155             onlineRefs = self.extractOnlineReferenceDetails(inputs) 
    156             if onlineRefs: 
    157                 c.atom.relatedLinks = onlineRefs 
    158                  
    159             self.saveAtomToExist(c.atom) 
    160                          
    161             #form = AtomFormSchema() 
    162             #validData = form.to_python(data) 
    163             #logging.info("Got data...") 
    164             #logging.info(validData) 
    165             #if validData: 
    166             #    link = Atom(**validData) 
    167              
    168             # if we're dealing with an expandable text input, re-render this now 
    169             if int(saveData) > 1: 
    170                 logging.debug("Doing a partial re-render") 
    171                 c.key=request.params['key'] 
    172                 c.default=request.params[c.key] 
    173                 logging.debug(c.key) 
    174                 logging.debug(c.default) 
    175  
    176                 c.blkfrag=1 
    177                 return render("genshi", 'utils', fragment=True) 
    178          
     174         
     175        self.addRelatedLinksDropDowns() 
    179176 
    180177        try: 
     
    195192        response.status_code = 400 
    196193        return render('error') 
     194 
     195 
     196    def addRelatedLinksDropDowns(self): 
     197        ''' 
     198        Set up the drop down lists required for the selection of online ref links 
     199        ''' 
     200        # at the very least, we need a simple drop down list with no preselected 
     201        # values 
     202        logging.debug("Setting up drop down lists for related links") 
     203        vtd = VTD() 
     204        c.relatedLinkTerms = self.__getDropdown(vtd.getValidTypes(vtd.ONLINE_REF_CATEGORY)) 
     205         
     206        c.relatedLinkSelectedLists = {} 
     207        for link in c.atom.relatedLinks: 
     208            logging.debug("Adding dropdown for related link, '%s'" %(str(link))) 
     209            c.relatedLinkSelectedLists[str(link)] = \ 
     210                self.__getDropdown(vtd.getValidTypes(vtd.ONLINE_REF_CATEGORY), \ 
     211                                                     selected=link.rel) 
     212 
     213        logging.debug("Finished setting up drop down lists") 
    197214 
    198215 
     
    223240                # existing entries, potentially 
    224241                author = Person(personType = authorType) 
     242                # check if the remove checkbox has been set 
    225243                keyStem = ".".join(keyBits[0:2]) 
    226                 author.name = inputs.get(keyStem + '.name') or "" 
    227                 author.uri = inputs.get(keyStem + '.uri') or "" 
    228                 author.role = inputs.get(keyStem + '.role') or "" 
    229                  
    230                 logging.info("Adding new author info") 
    231                 logging.debug("Extracted author (type:'%s', name:'%s', uri:'%s', role:'%s')" \ 
    232                               %(author.type, author.name, author.uri, author.role)) 
    233                 authors.append(author) 
     244                if inputs.get(keyStem + ".remove"): 
     245                    logging.info("Removing author data") 
     246                else: 
     247                    author.name = inputs.get(keyStem + '.name') or "" 
     248                    author.uri = inputs.get(keyStem + '.uri') or "" 
     249                    author.role = inputs.get(keyStem + '.role') or "" 
     250                     
     251                    logging.info("Adding new author info") 
     252                    logging.debug("Extracted author (type:'%s', name:'%s', uri:'%s', role:'%s')" \ 
     253                                  %(author.type, author.name, author.uri, author.role)) 
     254                    authors.append(author) 
    234255                processedAuthors.append(keyBits[1]) 
    235256 
     
    258279                    link.href = inputs.get(keyStem + '.href') or "" 
    259280                    link.title = inputs.get(keyStem + '.title') or "" 
    260                     link.rel = inputs.get(keyStem + '.rel') or "" 
    261281                     
    262                     logging.info("Adding new online reference info") 
    263                     logging.debug("Extracted online reference (href:'%s', title:'%s', rel:'%s')" \ 
    264                                   %(link.href, link.title, link.rel)) 
    265                     links.append(link) 
     282                    if inputs.get(keyStem + ".remove"): 
     283                        logging.info("Removing online reference data") 
     284                    else: 
     285                        # NB, this is in the format vocabURL--termID, so requires further 
     286                        # processing 
     287                        link.rel = self.getLatestTermURLFromDropDownInput(inputs.get(keyStem + '.rel')) 
     288                             
     289                        logging.info("Adding new online reference info") 
     290                        logging.debug("Extracted online reference (href:'%s', title:'%s', rel:'%s')" \ 
     291                                      %(link.href, link.title, link.rel)) 
     292                        links.append(link) 
    266293                    processedLinks.append(keyBits[1]) 
    267294                else: 
     
    271298        return links 
    272299                 
     300 
     301    def getLatestTermURLFromDropDownInput(self, inputVal): 
     302        ''' 
     303        Term ID and vocabURL are specified in the drop down menus 
     304        - using the input from this, return the lastest full href to the 
     305        term ID 
     306        ''' 
     307        termData = inputVal.split('--') 
     308        return VTD().getCurrentVocabURI(termData[0]) + \ 
     309                        "/" + termData[1] 
     310 
    273311 
    274312    def saveAtomToExist(self, atom): 
     
    299337            self.__setup() 
    300338            inputs = request.params 
     339            inputs['atomTypeID'] = inputs.get('atomTypeID').split('--')[1] 
     340            inputs['providerID'] = inputs.get('providerID').split('--')[1] 
    301341            logging.debug("Input params, '%s'" %inputs) 
    302             atom = self.saveAtomToExist(Atom(**dict(inputs))) 
     342            self.saveAtomToExist(Atom(**dict(inputs))) 
     343             
    303344            h.redirect_to (controller = 'editatom', action='edit', \ 
    304                            uri = atom.ndgURI, saveData = 0) 
     345                           uri = atom.ndgURI) 
    305346             
    306347        logging.info("Setting up atom create template") 
     
    309350         
    310351        # set up the drop down content 
    311         vocabData = VTD() 
    312         c.atomTypes = self.__getDropdown(vocabData.getValidTypes(vocabData.ATOM_CATEGORY)) 
    313         c.providerIDs = self.__getDropdown(vocabData.getValidTypes(vocabData.PROVIDER_CATEGORY)) 
     352        vtd = VTD() 
     353        c.atomTypes = self.__getDropdown(vtd.getValidTypes(vtd.ATOM_CATEGORY)) 
     354        c.providerIDs = self.__getDropdown(vtd.getValidTypes(vtd.PROVIDER_CATEGORY)) 
    314355 
    315356        try: 
     
    337378            logging.debug("(current val:'%s')" %selected) 
    338379        r='' 
     380        # NB, need to include both vocabURL and term ID for the data to be 
     381        # meaningful 
    339382        for val in list: 
    340383            default='' 
    341             if selected and val.termID == selected: 
     384            # NB, the selected val will be the full, latest term url - so only 
     385            # compare the start and end for match 
     386            if selected and selected.endswith(val.termID) and \ 
     387                selected.startswith(val.vocabURL): 
    342388                default='selected="selected"' 
    343             r+='<option value="%s" %s>%s</option>'%(val.termID, default, \ 
    344                                                     val.title or val.termID) 
     389            r+='<option value="%s--%s" %s>%s</option>' %(val.vocabURL, \ 
     390                val.termID, default, val.title or val.termID) 
     391         
     392        logging.debug("- produced drop down contents: '%s'" %r) 
    345393        return r 
    346394 
  • TI05-delivery/ows_framework/trunk/ows_server/ows_server/templates/atom_functions.html

    r4244 r4250  
    6767                                <th align="left">${dataType}</th> 
    6868                        </span> 
     69                        <span py:if="editLink and listOfPeople" py:strip=""> 
     70                                <th align="center">Remove</th> 
     71                        </span> 
    6972                </tr> 
    7073                    <tr py:for="i, person in enumerate(listOfPeople)"> 
     
    9295                                <a href="$person.uri">$person.uri</a> 
    9396                                </span> 
    94                         </td> 
     97                        </td> 
     98                        <span py:if="editLink and listOfPeople" py:strip=""> 
     99                                <td align="center"> 
     100                                        ${Markup(h.check_box(ptype + '.' + str(i) + '.remove'))} 
     101                                </td> 
     102                        </span> 
    95103                                </tr> 
    96104                                <!--! Add a few more rows when in edit mode  --> 
     
    106114                                    ${Markup(h.text_field(ptype + '.' + str(i) + '.uri'))} 
    107115                        </td> 
     116                        <span py:if="editLink" py:strip=""><td></td></span> 
    108117                                </tr> 
    109118                         
     
    220229                <div id = "$divID"> 
    221230                            <ul> 
    222                                 <li py:for="link in links"><a href="$link.href">${link.title or link.rel or link.href}</a></li> 
     231                                <li py:for="link in links"> 
     232                                    <?python 
     233                                # get the default display value 
     234                                displayVal = link.title  
     235                                if not displayVal: 
     236                                                        from ndgUtils.vocabtermdata import VocabTermData as VTD 
     237                                                        terms = VTD().getValidTypes(VTD.ONLINE_REF_CATEGORY) 
     238                                                        for term in terms: 
     239                                                                if link.rel.endswith(term.termID) and link.rel.startswith(term.vocabURL): 
     240                                                                        displayVal = term.title 
     241                                                                        break 
     242                                if not displayVal: 
     243                                                        displayVal = link.href or link.rel 
     244                                    ?> 
     245                                <a href="$link.href">${displayVal}</a> 
     246                                </li> 
    223247                        </ul> 
    224248                        </div> 
     
    244268            <table> 
    245269                <tr> 
     270                                <th align="left">Relation</th> 
    246271                        <th align="left">URI</th> 
    247272                        <th align="left">Title</th> 
    248                                 <th align="left">Relation</th> 
     273                        <th py:if="links" align="center">Remove</th> 
    249274                </tr> 
    250275                    <tr py:for="i, link in enumerate(links)"> 
     276                        <td> 
     277                                        ${Markup(h.select(refLabel + str(i) + '.rel', option_tags=c.relatedLinkSelectedLists[str(link)]))} 
     278                        </td> 
    251279                        <td> 
    252280                                    ${Markup(h.text_field(refLabel + str(i) + '.href', link.href))} 
     
    255283                                    ${Markup(h.text_field(refLabel + str(i) + '.title', link.title))} 
    256284                        </td> 
    257                         <td> 
    258                                     ${Markup(h.text_field(refLabel + str(i) + '.rel', link.rel))} 
    259                         </td> 
     285                        <td align="center"> 
     286                                ${Markup(h.check_box(refLabel + str(i) + '.remove'))} 
     287                        </td> 
    260288                                </tr> 
    261289                    <tr py:for="i in range(len(links), len(links) + extraRows)"> 
     290                        <td> 
     291                                        ${Markup(h.select(refLabel + str(i) + '.rel', option_tags=c.relatedLinkTerms))} 
     292                        </td> 
    262293                        <td> 
    263294                                    ${Markup(h.text_field(refLabel + str(i) + '.href'))} 
     
    266297                                    ${Markup(h.text_field(refLabel + str(i) + '.title'))} 
    267298                        </td> 
    268                         <td> 
    269                                     ${Markup(h.text_field(refLabel + str(i) + '.rel'))} 
    270                         </td> 
     299                        <td py:if="links" /> 
    271300                                </tr> 
    272301                        <tr><td> 
Note: See TracChangeset for help on using the changeset viewer.