1 # ===================================================================== 2 # groupPageMap: list pages in a W-TW group, in a sitemap-like fashion. 3 # 4 # Copyright (c) 2007-2011 Carlo Strozzi 5 # 6 # This program is free software; you can redistribute it and/or modify 7 # it under the terms of the GNU General Public License as published by 8 # the Free Software Foundation; version 2 dated June, 1991. 9 # 10 # This program is distributed in the hope that it will be useful, 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 # GNU General Public License for more details. 14 # 15 # You should have received a copy of the GNU General Public License 16 # along with this program; if not, write to the Free Software 17 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 # 19 # ===================================================================== 20 21 # ===================================================================== 22 # Local variables and functions 23 # ===================================================================== 24 25 cgi.group = () 26 cgi.group.literal = () 27 cgi.subcat = () 28 cgi.subcat.literal = () 29 cgi.paging = 0 # default is no paging. 30 cgi.blksize = () 31 cgi.scope = () 32 cgi.random = () 33 cgi.width = 1 # default. 34 cgi.outfmt = () 35 cgi.style = () 36 37 sort_cmd = () 38 39 # ===================================================================== 40 # Main program 41 # ===================================================================== 42 43 # Load call arguments. 44 csaGetArgs GET 45 46 ~ $'cgi.paging' 0 && csaTrue $TNS_PAGER_DEFAULT && cgi.paging = 1 47 48 ~ $'cgi.random' r && sort_cmd = unsorttable 49 50 . $CSA_ROOT/lib/group-stuff.rc 51 52 . $CSA_ROOT/lib/group-editor.rc 53 54 # Set template vars to provisional values. 55 tpl.var.tw.page = tw-group-pagemap 56 tpl.var.tw.page.object = $'tpl.var.tw.page' 57 tpl.var.html.title = $'tpl.var.tw.group'/$'tpl.var.tw.page' 58 59 if (csaIsFullPath --exists --quiet $CSA_TPL_ROOT/tw-group-pagemap.txt) { 60 # custom template. 61 tpl.include.html.body = $CSA_TPL_ROOT/tw-group-pagemap.txt 62 } else { 63 # default template. 64 tpl.include.html.body = $tw_dstem/tw-group-pagemap.txt 65 } 66 67 . $CSA_ROOT/lib/tpl-stuff.rc 68 69 # This needs to be set *after* group+cf has been read. 70 ~ $sort_cmd () && sort_cmd = (sorttable $TNS_PAGE_LIST_SORT) 71 72 # Create page widgets if necessary. 73 74 # Set target year/month for the calendar widget 75 if (~ $'tbl_page.p_vtime' ()) { 76 gencal_month = ($CSA_TIME_LOCAL(1) $CSA_TIME_LOCAL(2)) 77 } else { 78 * = ``(-,){echo -n $'tbl_page.p_vtime'} 79 ~ $#* 4 && shift # strip ranking 80 gencal_month = $* 81 } 82 83 gencal_xml = $tw_gstem/cal-$gencal_month(1)^-$gencal_month(2)^+xml 84 genarch_xml = $tw_gstem/year-links+xml 85 gencat_xml = $tw_gstem/cat-links+xml 86 87 if (!csaIsFullPath --exists --quiet $gencal_xml $genarch_xml $gencat_xml) { 88 89 # Set Principal Lock Semaphore(s) (PLS). 90 csaLock $tw_gstem/page+dat || csaExit.fault 91 pls_set = true 92 93 # Create main table if it does not yet exist. 94 if (!csaIsFullPath --exists --quiet $tw_gstem/page+dat) { 95 maketable --input \ 96 $CSA_ROOT/lib/page.xrf > $tw_gstem/page+dat || 97 csaExit.fault 0003 maketable 98 } 99 100 gencal_rcs = $tw_gstem/RCS/cal-$gencal_month(1)^-$gencal_month(2)^+xml,v 101 genarch_rcs = $tw_gstem/RCS/year-links+xml,v 102 gencat_rcs = $tw_gstem/RCS/cat-links+xml,v 103 104 gencat_mt = $tw_gstem/cat-mt+xml 105 gencat_mw = $tw_gstem/cat-mw+xml 106 107 gencat_mt_rcs = $tw_gstem/RCS/cat-mt+xml,v 108 gencat_mw_rcs = $tw_gstem/RCS/cat-mw+xml,v 109 110 widget_input = $tw_gstem/page+dat 111 112 . $CSA_ROOT/lib/widgets.rc 113 } 114 115 csaMkTemp tpl.include.tw.page 116 117 ~ $'cgi.subcat' too.short && cgi.subcat = () 118 119 #if (~ $'cgi.subcat' [a-z]*) { # F and f must allow for numeric args. 120 if (!~ $'cgi.subcat' ()) { 121 122 # If a full-text search was requested, then the specified subcat 123 # value will not be considered a subcat to search for, but rather 124 # a token that is to be matched against a few selected fields of 125 # the page table. The fields searched will be 'p_name' if 'f' was 126 # specified, and 'p_name', 'p_descr' and 'p_tags' if 'F' was specified. 127 # Both 'f' and 'F' can be followed by an integer value, like in 128 # 'f1', 'f2', 'F1', indicating the n. of characters that will 129 # be ignored *at the end* of the search pattern. This is meant 130 # to provide additional flexibility, and also to allow matching 131 # on plurals, at least in many common languages. If the specified 132 # integer is greater than the search pattern length, or if the 133 # pattern itself is already shorter than 3 characters, then the 134 # specified integer is ignored. 135 136 if (~ $'cgi.scope' f* F*) { 137 138 awktable -i $tw_gstem/page+dat \ 139 '-vp_='$'cgi.subcat' '-vs_='$'cgi.scope' -- ' 140 BEGIN{ 141 print "\001p_uri\t\001p_name\t\001p_descr\t\001k_page" \ 142 "\t\001p_vtime\t\001k_node\t\001p_link\t\001p_store" \ 143 "\t\001p_ctime\t\001p_tags\t\001p_etime" 144 split(s_,a_,"") 145 146 # undo the unixification process on search pattern if full-text. 147 if (a_[1] == "F") p_ = tolower('"$'cgi.subcat.literal'"') 148 149 # Rebuild pattern word-by-word here, and allow for matching on 150 # multiple, non-contiguous words. This will broaden the search, 151 # but better get more results than no results at all. 152 153 j_ = split(p_,c_,/[^a-z0-9]+/) 154 p_ = "" 155 for (x_ = 1; x_ <= j_; x_++) { 156 if ((i_=length(c_[x_])-a_[2]) > 2) 157 p_ = p_ ".*" substr(c_[x_],1,i_) 158 } 159 } 160 161 # Safety-measure for backward compatibility. 162 !p_etime {p_etime = 99} 163 164 a_[1] == "f" && $k_page ~ p_ { 165 # A match on the page name ranks higher. 166 split($p_vtime,b_,",") 167 if (b_[1] == "") $p_vtime = "00," $p_vtime 168 else $p_vtime = b_[1] $p_vtime 169 # A match on the subcat portion of page name ranks even higher. 170 m_ = "^" p_ 171 if ($k_page ~ m_) $p_vtime = substr($p_vtime,1,1) $p_vtime 172 173 print $p_uri,$p_name,$p_descr,$k_page,$p_vtime,\ 174 $k_node,$p_link,$p_store,$p_ctime,$p_tags,$p_etime 175 next 176 } 177 178 a_[1] == "F" && $k_page " " tolower($p_descr " " $p_tags) ~ p_ { 179 if ($k_page ~ p_) { 180 181 # A match on the page name ranks higher. 182 split($p_vtime,b_,",") 183 if (b_[1] == "") $p_vtime = "00," $p_vtime 184 else $p_vtime = b_[1] $p_vtime 185 # A match on the subcat portion of page name ranks even higher. 186 m_ = "^" p_ 187 if ($k_page ~ m_) $p_vtime = substr($p_vtime,1,1) $p_vtime 188 } 189 190 print $p_uri,$p_name,$p_descr,$k_page,$p_vtime,\ 191 $k_node,$p_link,$p_store,$p_ctime,$p_tags,$p_etime 192 }' | $sort_cmd | 193 { 194 # This is to output only unique page names regardless of subcat. 195 if (csaTrue $TNS_LOCAL_HACK_2) { 196 awktable -H -- '{ 197 tmp_ = $k_page; sub(/^[^.]+\./,"",tmp_) 198 if (p_[tmp_]) next; p_[tmp_] = 1; print 199 }' 200 } else cat 201 } > $'tpl.include.tw.page' 202 203 } else { 204 205 # Note that I do not test for errors at the end of the grep(1) pipeline 206 # here, as grep(1) may pick no lines (and thus exit non-zero) even 207 # under normal circumstances. 208 209 filtertable --input $tw_gstem/page+dat -- \ 210 grep -ie '^'$'cgi.subcat'\. | 211 getcolumn p_^(uri name descr) k_page p_vtime \ 212 k_node p_^(link store ctime tags) p_etime | 213 $sort_cmd > $'tpl.include.tw.page' 214 } 215 216 } else { 217 218 getcolumn --input $tw_gstem/page+dat \ 219 p_^(uri name descr) k_page p_vtime k_node \ 220 p_^(link store ctime tags) p_etime | 221 $sort_cmd > $'tpl.include.tw.page' || 222 csaExit.fault 0003 getcolumn/sorttable 223 } 224 225 # Static views do not correspond to actual pages on disk, 226 # so we need to toggle unapplicable sections in templates. 227 228 tpl.if.tw.ispage = '(::DEL:)' 229 tpl.fi.tw.ispage = '(:DEL::)' 230 tpl.if.tw.printable = '(::DEL:)' 231 tpl.fi.tw.printable = '(:DEL::)' 232 tpl.if.tw.isview = () 233 tpl.fi.tw.isview = () 234 235 # Handle sitemap-type response requests, see http://sitemaps.org . 236 if (~ $'cgi.outfmt' sitemap) { 237 tpl_file = (--file-root $tw_dstem tw-sitemap.xml) 238 CSA_RPC_FMT = rdf 239 240 # The default (simplified) XML prologue set by CSA would be 241 # perfectly OK here, but I set a non default one here as an 242 # example of how a local application can set it to whatever 243 # it likes/needs to produce XML responses in a local format. 244 # See also http://www.stylusstudio.com/xsllist/200405/post10320.html 245 # to learn why setting this particular prologue is completely 246 # needless here. 247 CSA_XMLTOP = '' 248 249 cgi.paging = 0 250 251 # Needed to trigger the appropriate behavior in _rdfprint(). 252 # Can be set to anything other than /dev/null, even to a 253 # non-existing file in this case, since it is not actually 254 # referred to by tw-sitemap.xml . 255 CSA_RDF_ORB = $'tpl.include.tw.page' 256 } 257 258 csaExit.ok --table $'tpl.include.tw.page' $tpl_file 259 260 # End of program.