paulb@219 | 1 | #!/usr/bin/env python |
paulb@219 | 2 | |
paulb@219 | 3 | "A dictionary example application." |
paulb@219 | 4 | |
paulb@219 | 5 | import WebStack.Generic |
paulb@353 | 6 | import XSLForms.Resources.WebResources |
paulb@219 | 7 | import XSLForms.Utils |
paulb@219 | 8 | import os |
paulb@219 | 9 | |
paulb@219 | 10 | # Site map imports. |
paulb@219 | 11 | |
paulb@219 | 12 | from WebStack.Resources.ResourceMap import MapResource |
paulb@560 | 13 | from WebStack.Resources.Selectors import EncodingSelector |
paulb@219 | 14 | from WebStack.Resources.Static import DirectoryResource |
paulb@219 | 15 | |
paulb@560 | 16 | # Configuration setting. |
paulb@560 | 17 | |
paulb@560 | 18 | encoding = "utf-8" |
paulb@560 | 19 | |
paulb@219 | 20 | # Resource classes. |
paulb@219 | 21 | |
paulb@353 | 22 | class DictionaryResource(XSLForms.Resources.WebResources.XSLFormsResource): |
paulb@219 | 23 | |
paulb@219 | 24 | "A simple resource providing dictionary lookup." |
paulb@219 | 25 | |
paulb@219 | 26 | resource_dir = os.path.join(os.path.split(__file__)[0], "Resources") |
paulb@219 | 27 | template_resources = { |
paulb@219 | 28 | "words" : ("words_template.xhtml", "words_output.xsl") |
paulb@219 | 29 | } |
paulb@219 | 30 | in_page_resources = { |
paulb@514 | 31 | "matches" : ("words", "words_output_entry.xsl", "matches-node"), |
paulb@514 | 32 | #"word" : ("words", "words_output_word.xsl", "word-node") |
paulb@219 | 33 | } |
paulb@219 | 34 | |
paulb@219 | 35 | def __init__(self, dict): |
paulb@219 | 36 | |
paulb@219 | 37 | "Initialise the resource with the given 'dict'." |
paulb@219 | 38 | |
paulb@219 | 39 | self.dict = dict |
paulb@219 | 40 | |
paulb@219 | 41 | def respond_to_form(self, trans, form): |
paulb@219 | 42 | |
paulb@219 | 43 | """ |
paulb@219 | 44 | Respond to a request having the given transaction 'trans' and the given |
paulb@219 | 45 | 'form' information. |
paulb@219 | 46 | """ |
paulb@219 | 47 | |
paulb@219 | 48 | in_page_resource = self.get_in_page_resource(trans) |
paulb@219 | 49 | parameters = form.get_parameters() |
paulb@219 | 50 | documents = form.get_documents() |
paulb@219 | 51 | |
paulb@219 | 52 | # Ensure the presence of a document. |
paulb@219 | 53 | |
paulb@219 | 54 | if documents.has_key("words"): |
paulb@219 | 55 | words = documents["words"] |
paulb@219 | 56 | else: |
paulb@219 | 57 | words = form.new_instance("words") |
paulb@219 | 58 | |
paulb@219 | 59 | # Add and remove elements according to the selectors found. |
paulb@219 | 60 | |
paulb@219 | 61 | selectors = form.get_selectors() |
paulb@219 | 62 | XSLForms.Utils.remove_elements(selectors.get("remove")) |
paulb@219 | 63 | XSLForms.Utils.add_elements(selectors.get("add"), "entry") |
paulb@219 | 64 | |
paulb@219 | 65 | # Ensure all entries have a matches element. |
paulb@219 | 66 | # Ensure all matches elements have at least one choice. |
paulb@219 | 67 | # Copy selected matches to their corresponding text field. |
paulb@219 | 68 | |
paulb@223 | 69 | all_entries = words.xpath("words/entry") |
paulb@223 | 70 | |
paulb@223 | 71 | for entry in all_entries: |
paulb@219 | 72 | matches_list = entry.xpath("matches") |
paulb@219 | 73 | if len(matches_list) == 0: |
paulb@219 | 74 | matches = words.createElement("matches") |
paulb@219 | 75 | entry.appendChild(matches) |
paulb@219 | 76 | else: |
paulb@219 | 77 | matches = matches_list[0] |
paulb@219 | 78 | |
paulb@219 | 79 | if len(entry.xpath("matches/match-enum")) == 0: |
paulb@219 | 80 | match_enum = words.createElement("match-enum") |
paulb@219 | 81 | match_enum.setAttribute("word", "") |
paulb@219 | 82 | matches.appendChild(match_enum) |
paulb@219 | 83 | |
paulb@219 | 84 | # Find requested search locations. |
paulb@219 | 85 | |
paulb@219 | 86 | if selectors.has_key("search"): |
paulb@219 | 87 | entries = selectors["search"] |
paulb@220 | 88 | elif in_page_resource == "matches": |
paulb@223 | 89 | entries = all_entries |
paulb@219 | 90 | else: |
paulb@219 | 91 | entries = [] |
paulb@219 | 92 | |
paulb@219 | 93 | # Transform, adding dictionary information. |
paulb@219 | 94 | |
paulb@219 | 95 | for entry in entries: |
paulb@219 | 96 | word = entry.getAttribute("word") |
paulb@219 | 97 | if word != "": |
paulb@219 | 98 | matches = entry.xpath("matches")[0] |
paulb@219 | 99 | for found_word in self.dict.find(word): |
paulb@219 | 100 | match_enum = words.createElement("match-enum") |
paulb@219 | 101 | match_enum.setAttribute("word", found_word) |
paulb@219 | 102 | matches.appendChild(match_enum) |
paulb@219 | 103 | |
paulb@223 | 104 | # Copy selected values into text fields. |
paulb@223 | 105 | # NOTE: Since libxml2dom does not guarantee node equality for two nodes |
paulb@223 | 106 | # NOTE: referring to the same thing, we cannot just loop over all the |
paulb@223 | 107 | # NOTE: entries and query whether they reside in the search locations. |
paulb@223 | 108 | |
paulb@223 | 109 | for entry in all_entries: |
paulb@223 | 110 | matches = entry.xpath("matches")[0] |
paulb@223 | 111 | if matches.hasAttribute("word"): |
paulb@223 | 112 | word = matches.getAttribute("word") |
paulb@223 | 113 | if word != "" and word.startswith(entry.getAttribute("word")): |
paulb@223 | 114 | entry.setAttribute("word", word) |
paulb@223 | 115 | |
paulb@219 | 116 | # Start the response. |
paulb@219 | 117 | |
paulb@560 | 118 | trans.set_content_type(WebStack.Generic.ContentType("application/xhtml+xml", encoding)) |
paulb@219 | 119 | |
paulb@219 | 120 | # Ensure that an output stylesheet exists. |
paulb@219 | 121 | |
paulb@219 | 122 | if in_page_resource in self.in_page_resources.keys(): |
paulb@514 | 123 | trans_xsl = self.prepare_fragment(in_page_resource) |
paulb@296 | 124 | stylesheet_parameters = self.prepare_parameters(parameters) |
paulb@219 | 125 | else: |
paulb@219 | 126 | trans_xsl = self.prepare_output("words") |
paulb@296 | 127 | stylesheet_parameters = {} |
paulb@219 | 128 | |
paulb@219 | 129 | # Complete the response. |
paulb@219 | 130 | |
paulb@219 | 131 | self.send_output(trans, [trans_xsl], words, stylesheet_parameters) |
paulb@485 | 132 | #from XSLTools import XSLOutput |
paulb@485 | 133 | #import sys |
paulb@485 | 134 | #proc = XSLOutput.Processor([trans_xsl], parameters=stylesheet_parameters) |
paulb@485 | 135 | #proc.send_output(sys.stderr, "iso-8859-1", words) |
paulb@219 | 136 | |
paulb@219 | 137 | # Site map initialisation. |
paulb@219 | 138 | |
paulb@219 | 139 | def get_site(dict): |
paulb@219 | 140 | |
paulb@219 | 141 | """ |
paulb@219 | 142 | Return a simple Web site resource using the given 'dict' - a dictionary |
paulb@219 | 143 | employed by the application. |
paulb@219 | 144 | """ |
paulb@219 | 145 | |
paulb@219 | 146 | # Get the main resource and the directory used by the application. |
paulb@219 | 147 | |
paulb@219 | 148 | dictionary_resource = DictionaryResource(dict) |
paulb@219 | 149 | directory = dictionary_resource.resource_dir |
paulb@219 | 150 | |
paulb@219 | 151 | # Make a simple Web site. |
paulb@219 | 152 | |
paulb@219 | 153 | resource = MapResource({ |
paulb@219 | 154 | # Static resources: |
paulb@219 | 155 | "scripts" : DirectoryResource(os.path.join(directory, "scripts"), {"js" : "text/javascript"}), |
paulb@219 | 156 | # Main page and in-page resources: |
paulb@227 | 157 | "" : dictionary_resource, |
paulb@227 | 158 | "matches" : dictionary_resource |
paulb@219 | 159 | }) |
paulb@219 | 160 | |
paulb@560 | 161 | return EncodingSelector(resource, encoding) |
paulb@219 | 162 | |
paulb@514 | 163 | # Resource preparation ahead of time - useful for making installations. |
paulb@514 | 164 | |
paulb@514 | 165 | def prepare_resources(): |
paulb@514 | 166 | for cls in [DictionaryResource]: |
paulb@514 | 167 | XSLForms.Resources.WebResources.prepare_resources(cls) |
paulb@514 | 168 | |
paulb@219 | 169 | # vim: tabstop=4 expandtab shiftwidth=4 |