From: Gerfried Fuchs Date: Sun, 31 Oct 2010 13:23:32 +0000 (+0100) Subject: Initial import of Kalle's Theme X-Git-Url: https://git.deb.at/?p=deb%2Fmoinmoin.git;a=commitdiff_plain;h=f5041d6a290ec7ef657e9e24333ca1c80c08d72e Initial import of Kalle's Theme --- f5041d6a290ec7ef657e9e24333ca1c80c08d72e diff --git a/README b/README new file mode 100644 index 0000000..2d3a2d2 --- /dev/null +++ b/README @@ -0,0 +1,9 @@ +This is about Kalle's themeing for moinmoin, which is used on wiki.debian.org. + +URL: http://www.kalleswork.net/projects/debian/wiki/ +Testsite: http://wiki.debian.org/ (follow instructions from above) + +Expected configuration: + debwiki/ goes to /usr/share/moin/htdocs/debwiki + wikiconfig.py.debwiki is a configuration template for /etc/moin/ + theme/ contains the files for the theme directory of your data diff --git a/debwiki/config.html_head b/debwiki/config.html_head new file mode 100644 index 0000000..d0119df --- /dev/null +++ b/debwiki/config.html_head @@ -0,0 +1 @@ +

hello!

diff --git a/debwiki/css/Pics/gradient.png b/debwiki/css/Pics/gradient.png new file mode 100644 index 0000000..dc4a8b8 Binary files /dev/null and b/debwiki/css/Pics/gradient.png differ diff --git a/debwiki/css/Pics/greydot.png b/debwiki/css/Pics/greydot.png new file mode 100644 index 0000000..ec23c01 Binary files /dev/null and b/debwiki/css/Pics/greydot.png differ diff --git a/debwiki/css/Pics/openlogo-50.png b/debwiki/css/Pics/openlogo-50.png new file mode 100644 index 0000000..f4e75fc Binary files /dev/null and b/debwiki/css/Pics/openlogo-50.png differ diff --git a/debwiki/css/Pics/reddot.png b/debwiki/css/Pics/reddot.png new file mode 100644 index 0000000..76cc993 Binary files /dev/null and b/debwiki/css/Pics/reddot.png differ diff --git a/debwiki/css/common.css b/debwiki/css/common.css new file mode 100644 index 0000000..9e9ec0b --- /dev/null +++ b/debwiki/css/common.css @@ -0,0 +1,2 @@ +@import url("modernized-common.css"); +@import url("debwiki.css"); diff --git a/debwiki/css/debian.css b/debwiki/css/debian.css new file mode 100644 index 0000000..29d44a3 --- /dev/null +++ b/debwiki/css/debian.css @@ -0,0 +1,753 @@ +/* + www.debian.org stylesheet proposal + + Kalle Soderman, 2008 debian.css + + Copyleft : This work is free, you can copy, spread, and modify it under + the terms of the Free Art License http://artlibre.org/licence/lal/en/ + + + Font size table (Browser default 16px) + + pixels relative + -------------------- + 36px 2.25em + 31px 0.5161em + 24px 1.5em + 21px 1.3125em + 18px 1.125em + 16px 1em + 14px 0.875em + 12px 0.75em + 11px 0.6875em + 10px 0.625em + 9px 0.5625em + -------------------- + */ + +/* Reset */ + +html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, +blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, +font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, dl, +dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, +tfoot, thead, tr, th, td { + margin: 0; + padding: 0; + border: 0; + outline: 0; + font-weight: inherit; + font-style: inherit; + font-size: 100%; + font-family: inherit; + vertical-align: baseline; +} + +body { line-height: 1; color: black; background: white; } +ol, ul { list-style: none; } +table { border-collapse: separate; border-spacing: 0; } +blockquote, q { quotes: "" ""; } +html { background-color: transparent; } +:focus { outline: 0; } +caption, th, td { text-align: left; font-weight: normal; } +blockquote:before, blockquote:after, q:before, q:after { content: ""; } + +/* Main */ + +body { + margin: 0; + font: normal 100% sans-serif; + line-height: 1.5; + color: #222; + background-color: white; + background-image:url('Pics/gradient.png'); + background-position: 0 0; + background-repeat: repeat-x; + /* Uncomment to show baseline grid + background-image: url('24grid.png'); + background-position: 30px 9px; + */ +} +#outer { + margin: 0 10px 0 62px; +} +#inner { + position: relative; +} +#maincol { + margin: 0 15em 1.5em 0; +} + +/* Header */ + +#header { + margin:0; + padding:0 10px 0 62px; +} +#header a:link +, #header a:visited +, #second-nav a:link +, #second-nav a:visited { + text-decoration: none; +} +#header a:hover +, #second-nav a:hover { + text-decoration: underline; +} +#breadcrumbs { + margin:0; + font-size: 0.75em; + text-transform: lowercase; + line-height: 2; + background-color: transparent; + background-color: #f5f6f7; + border-bottom: 1px solid #d2d3d7 ; + min-height: 20px; +} +#breadcrumbs:before { + content: "/"; + margin-left: 0.5em; + margin-right: 0.5em; +} +p.section { + margin: 0; + padding: 0 5px 0 5px; + font-family:monospace; + line-height: 16px; + color:white; + text-transform: uppercase; + letter-spacing: 0.08em; + position:absolute; + top: 0px; + left:62px; + background-color: #c70036; +} +#navbar { + background-color: transparent; + list-style:none; + display:block; + border-bottom:1px solid #c70036; + text-indent:0; + padding: 0; + margin-top:0; + margin-bottom:0; +} +#navbar ul { + margin: 0; + padding: 0; + clear: both; + overflow: hidden; + min-height: 45px; +} +#navbar li { + list-style: none; + float: left; + padding: 0; + margin: 0; +} +#navbar a:link +, #navbar a:visited { + padding: 1.75em 1em 0.25em 1em; + border-left: 1px solid transparent; + border-right: 1px solid transparent; + display: block; + text-decoration: none; +} +#navbar a:visited { + color: #54638c; +} +#navbar a:hover +, #navbar a:visited:hover { + background-color: #efefef; + border-left: 1px solid #d2d3d7; + border-right: 1px solid #d2d3d7; + text-decoration: underline; +} +#searchbox { + text-align:left; + line-height: 1; + margin: 0 10px 0 0.5em; + padding: 1px 0 1px 0; + position: absolute; + top:0; + right:0; + font-size: 0.75em; +} +#searchbox p { + margin: 0; + padding: 0; +} +#upperheader { + margin:0; + padding:0; +} +#logo { + position:absolute; + top:0; + left:0; + padding: 0; + background-color: transparent; + border: 1px solid transparent; + border-top: 0; + width: 61px; + height: 5.07em; + min-height: 65px; +} +#logo a { + display: block; + position: relative; + padding: 0 5px 0 5px; + height: 100%; + min-height: 65px; +} +#logo img { + margin-top: 5px; + position: absolute; + bottom: 0.3em; + overflow: auto; +} +#logo:hover { + border: 1px solid #d2d3d7 ; + border-top: 0; + background-color: #eee; +} + +/* Links */ + +a:link { + color: #0035c7; + text-decoration: underline; +} +a:visited { + color: #54638c; +} +a:link:hover { + text-decoration: none; + color: #00207a; +} +a:visited:hover { + text-decoration: none; +} +a:active { + color:#c2c3c7; +} +a img { + border:0; +} + +/* Secondnav */ + +#second-nav { + width: 16em; + font-size: 0.75em; + line-height: 1.5; + position: absolute; + top: 0; + right: 0; + margin: 3em 0 0 0; + padding: 0 0 0 1em; + border-left: 1px solid #d2d3d7 ; +} +#second-nav ul { + padding:0; + margin:0; + list-style:none; +} +#second-nav ul ul { + margin-left: 1em; +} +#second-nav li { + font-weight: normal; + margin:0; + padding:0; +} +#second-nav p { + line-height: 2; + font-weight: bold; + margin: 0; +} +#second-nav h2 { + margin:0; +} + +/* Typography */ + +p { + margin: 1.5em 0 1.5em 0; +} +strong { + font-weight: bold; +} +em { + font-style: italic; + color: #444; +} +small { + font-size: 0.75em; +} +sup { + font-size: 0.75em; + vertical-align:top; +} +h1 +, h2 +, h3 +, h4 +, h5 +, h6 { + font-weight: 600; + color: black; +} +h1 { + font-weight: normal; + font-size: 1.8em; + line-height: 0.83333; + margin: 0.83333em 0 0.83333em 0; +} +h2 { + font-size: 1.4em; + font-weight: normal; + line-height: 1.0714286; + margin: 1.0714286em 0 1.0714286em 0; +} +h3 { + font-size: 1.125em; + line-height: 1.333em; + margin: 1.333em 0 0 0; +} +h4 { + font-weight: normal; + font-style: italic; + margin: 1.5em 0 1.5em 0; + color: #444; +} +h5 { + font-style: italic; + font-size: 0.75em; + margin: 2em 0 2em 0; +} +ol,ul { + padding-left: 1.5em; + margin-left:0; + margin: 1.5em 0 1.5em 0; +} +ol>ol, ul>ul, li>ol, li>ul { + margin: 0; +} + +ol { + list-style-type: decimal; +} +ul { + list-style-type: disc; +} +th { + font-weight: bold; + margin: 1.5em 0 1.5em 0; +} +hr { + border: none; + background-color: #bbb; + height: 1px; + margin: 1.4375em 0 1.5em 0; +} +pre { + margin: 1.5em 0 1.5em 0; + overflow: auto; + font-family: monospace; + white-space: pre; + color: black; +} +tt, code { + font-family: monospace; + white-space: pre; + color: black; +} +dd { + margin: 0 0 0 1.5em; +} +blockquote { + font-size: 0.75em; + margin: 2em; + line-height: 2; +} +cite { + font-style: italic; + color: #444; +} +acronym, abbr { + text-transform: uppercase; + font-size: 0.9em; +} +.toc { + font-size: 0.75em; + list-style:none; + background-image: url('Pics/greydot.png'); + background-position: bottom left; + background-repeat: repeat-x; + line-height:1.833; + padding: 0; + max-width: 62%; + margin: 2em 0 2em 0; +} +.toc li { + background-image: url('Pics/greydot.png'); + background-position: top left; + background-repeat: repeat-x; + padding: 0.0833em 0 0.0833em 0; + } +.toc a { + display:block; + text-decoration: none; +} +.toc a:hover { + display:block; + background-color: #f0f0f4; + text-decoration: underline; +} + +/* Sitemap */ + +.card { + clear:both; + margin:1.5em 0 1.5em 0; + background-position: 0 -50px; + background-repeat: repeat-x; + padding:0; +} +.card ul { +} +.card ul li { + list-style:none; +} +.card h2 { +} +.lefthalf { + float:left; +} +.righthalf { + margin-left:50%; +} +.lefthalf ul { + margin-top:0; +} + +/* Footer */ + +#footer { + font-size: 0.75em; + border: 1px solid #dfdfe0; + padding:1em; + background-color: #f5f6f7; + margin: 0 0 0 0; + line-height: 1.5em; + border-left: 0; + border-right: 0; +} +#footer p { + margin: 1em 0 1em 0; +} +#footer hr { + border-top: 1px solid #d2d3d7; + border-bottom: 1px solid white; + height: 0; +} +#footer .editbar li { + display: inline; + margin-right: 2em; +} +#footer .info { +} +#fineprint { + margin-bottom: 1em; +} +#footermap { + list-style:none; + margin: 0 0 0 0; + padding: 0; + width:100%; + overflow: hidden; + border: 0; +} +ul#footermap-cola a +, ul#footermap-colb a +, ul#footermap-colc a +, ul#footermap-cold a +, ul#footermap-cole a { + padding-left: 0; +} +ul#footermap-cola +, ul#footermap-colb +, ul#footermap-colc +, ul#footermap-cold +, ul#footermap-cole { + float:left; + width: 19%; + min-width: 11em; + height: 12em; /* Update when adding items */ + margin:0 1% 0 0; + padding: 2em 0 0 0; + list-style: none; +} +ul#footermap-cole { + width: 18.9%; + margin-right:0; +} +#footermap-wrap { + padding:2em; + border-top: 1px solid white; +} +#footermap a { + margin: 0; +} +#footermap ul{ + list-style: none; + padding:0; +} +#footermap li { + text-indent:0; + background-color: transparent; + font-weight:bold; +} +#footermap li ul { + margin: 0; + padding: 0: +} +#footermap li li { + margin:0; + text-indent:0; + padding:0; + font-weight:normal; + border:0; + background-image:none; + background-color:transparent; +} +#serverselect { +} +#serverselect input +, #serverselect option +, #serverselect select { +} +#serverselect ul { + display: inline; + margin-left: 2em; +} +#serverselect li { + list-style: none; + display: inline; + padding:0 1em 0 1em; + margin:0; +} +#serverselect form p { + margin:0; + padding:0; + line-height: 1; +} +.lcol50 { + float: left; + width: 49%; + font-size:0.75em; + margin:0 0 0 0; + padding:0 0.5em 0 0; +} +.lcol50 h2 { + margin-top:0; +} +.rcol50 { + margin:0 0 0 51%; + padding:0; + font-size:0.75em; +} +form#pageLang { + display: inline; +} + +/* Extras */ + +input:focus { + background-color:#FFFFCB; + +} +.hidecss { + display: none; +} +.clear { + clear:both +} +#clear { + clear:both; + border:0; + height:1px; + display:block; +} +.quicklist:before { + content: "Quick Links: "; + font-weight: bold; +} +.quicklist { + list-style: none; + font-size: 0.75em; + margin: 2em 0 2em 0; + padding:0; + text-indent:0; + line-height: 2em; +} +.quicklist li { + display:inline; +} +.item p{ + margin: 0; +} +.item h2 +, .item p +, .item ul{ + margin-right: 10px +} +.item h2 +, .item h3 +, .item h4 +, .item h5 { + margin-top: 0; +} +.line { + padding: 0; + width: auto; + overflow: hidden; + } +div.downloads { + border-top: 0.17em solid #339900; + margin: 1.33em 0 0 0; +} +.downloads ul.downlist { + margin:0; +} +div.downloads .col50 { + border-top: 0.15em solid #339900; +} +ul.downlist { + padding-left: 30px; + text-indent:0; + background: url('Pics/emblem-downloads.png') no-repeat 0 0.15em; + /* + * border-top: 0.17em solid #339900; + */ +} +ul.quicklist.downlist { + border-top: 0.15em solid #339900; + padding-top: 0.25em; + margin-top: 1.6em; +} +ul.downlist li { + display: inline; +} +ul.downlist li:after { + content: ', '; +} +ul.downlist li:last-child:after { + content: ''; +} +div.tip +, div.important +, div.warning +, div.note { + padding:0 2em 0 4em; + margin: 1.85em 0 1.85em 0; + background-repeat: no-repeat; + background-position: 0.5em 1em; + font-size: 0.75em; + line-height: 2em; + background-color:#FFFFCB; + border:0.15em solid #CCCCA3; +} +div.tip p +, div.important p +, div.warning p +, div.note p { + margin: 1em 0 1em 0; +} +div.tip { + background-image: url('Pics/admon-tip.png'); +} +div.important{ + background-image: url('Pics/admon-important.png'); +} +div.warning { + background-image: url('Pics/admon-warning.png'); +} +div.note { + background-image: url('Pics/admon-note.png'); +} + +/* Layout Elements */ + +.col50 +, .cardleft +, .cardright { + width:47.5%; + float: left; + padding-bottom: 1.5em; +} +.lastcol +, .cardright { + margin: auto; + width: 47.5%; + float:left; + padding-right: 0; + margin-left: 5%; +} +.lastcol h2 +, .lastcol p +, .lastcol ul { + margin-right:0; +} +.cardleft h2 { + margin-right: 1em; +} +.cardright div { + margin-left: 1.5em; +} +.cardright h2 { + margin-left: 1em; +} +.votemenu a { + display:block; +} +table.vote td, table.vote th { + padding-right: 1.5em; +} +#maincol.with-toolbox { + margin-right: 14em; +} +table.vendors { +/* border-bottom: 1px solid #a9abb3; + border-top: 1px solid #a9abb3; */ + border-bottom: 0.15em solid #666; + border-top: 0.15em solid #666; + display: block; + width: auto; + font-size: 0.75em; + line-height: 2em; + margin-bottom: 4em; + margin-top: -0.169em; +} +table td { + padding-right: 1.5em; +} +table.vendors tr { + width: 100%; +} +table th { + padding-right: 1.5em; +} +table.vendors td { + background-image: url(Pics/greydot.png); + background-position: top left; + background-repeat: repeat-x; +} +#pageLang p, #pageLang form { + display: inline; +} +.inline a { + float: left; + margin-right: 1em; +} diff --git a/debwiki/css/debian.css.old b/debwiki/css/debian.css.old new file mode 100644 index 0000000..f372aaa --- /dev/null +++ b/debwiki/css/debian.css.old @@ -0,0 +1,774 @@ +/* + * www.debian.org stylesheet proposal + * + * Kalle Soderman, 2008 debian.css + * + * Copyleft : This work is free, you can copy, spread, and modify it under + * the terms of the Free Art License http://artlibre.org/licence/lal/en/ + * + * + * Font size table + * --------------- + * Browser default 16px + * pixels relative + * 36px 2.25em + * 31px 0.5161em + * 24px 1.5em + * 21px 1.3125em + * 18px 1.125em + * 16px 1em + * 14px 0.875em + * 12px 0.75em + * 11px 0.6875em + * 10px 0.625em + * 9px 0.5625em + */ +@media screen { +/* + * reset + */ + +html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, +blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, +font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, dl, +dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, +tfoot, thead, tr, th, td { + margin: 0; + padding: 0; + border: 0; + outline: 0; + font-weight: inherit; + font-style: inherit; + font-size: 100%; + font-family: inherit; + vertical-align: baseline; +} + +:focus { + outline: 0; +} + +body { + line-height: 1; + color: black; + background: white; +} + +ol, ul { + list-style: none; +} + +table { + border-collapse: separate; + border-spacing: 0; +} + +caption, th, td { + text-align: left; + font-weight: normal; +} + +blockquote:before, blockquote:after, +q:before, q:after { + content: ""; +} + +blockquote, q { + quotes: "" ""; +} + +html { + background-color: transparent; +} + + +/* + * start + */ + +body { + margin: 0; + font: normal 100% sans-serif; + line-height: 1.5; + color: #222; + background-color: white; +} + +#outer { + margin: 0 10px 0 62px; +} + +#maincol { + margin: 0 0 1.5em 0; + } + +/* + * Header + */ + +#header { + margin:0; + padding:0 10px 0 62px; + background-image:url('Pics/gradient.png'); + background-position: 0 0; + background-repeat: repeat-x; +} + +#header a:link +, #second-nav a:link { + text-decoration: none; +} + +#header a:hover +, #second-nav a:hover { + text-decoration: underline; +} + +#breadcrumbs { + font-size: 0.75em; + background-color: transparent; + background-color: #f5f6f7; + margin:0; + border-bottom: 1px solid #d2d3d7 ; + text-transform:lowercase; + line-height: 2; +} + +p.section { + font-family:monospace; + position:absolute; + top: 0px; + left:62px; + text-transform: uppercase; + letter-spacing: 0.08em; + background-color: #c70036; + line-height: 16px; + color:white; + padding: 0 5px 0 5px; + margin:0; +} + +#navbar { + background-color: transparent; + list-style:none; + display:block; + border-bottom:1px solid #c70036; + text-indent:0; + padding: 0; + margin-top:0; + margin-bottom:0; +} + +#navbar ul { + margin:0 ; + padding:0 ; + clear: both; + overflow: hidden; +} + +#navbar li { + list-style: none; + float: left; + padding: 0; + margin: 0; +} + +#navbar a:link +, #navbar a:visited { + padding: 1.75em 1em 0.25em 1em; + border-left: 1px solid transparent; + border-right: 1px solid transparent; + display: block; + text-decoration: none; +} + +#navbar a:visited { + color: #54638c; +} + +#navbar a:hover +, #navbar a:visited:hover { + background-color: #efefef; + border-left: 1px solid #d2d3d7; + border-right: 1px solid #d2d3d7; +} + +#sitetools { + text-align:left; + margin: 0 10px 0 0; + padding: 0px 0 1px 0; + position: absolute; + top:0; + right:0; + border-right: 1px solid white; + border-left: 1px solid #d2d3d7; + line-height: 1; +} + +#upperheader { + margin:0; + padding:0; +} + +#logo { + position:absolute; + top:0; + left:0; + padding: 0; + background-color: transparent; + border: 1px solid transparent; + border-top: 0; + width: 61px; + height: 5.05em; +} + +#logo a { + display: block; + position: relative; + padding: 0 5px 0 5px; + height: 100%; +} + +#logo img { + margin-top: 5px; + position: absolute; + bottom: 0.3em; + overflow: auto; +} + +#logo:hover { + border: 1px solid #d2d3d7 ; + border-top: 0; + background-color: #eee; +} + +/* + * Links + */ + +a:link { + color: #0035c7; + text-decoration: underline; +} + +a:visited { + color: #54638c; +} + +a:hover { + text-decoration: none; + color: #00207a; +} + +a:active { + color:#c2c3c7; +} + +a img { + border:0; +} + +/* + * Secondnav + */ + +#second-nav { + width: 16em; + float:right; + padding:0 0 0 1.5em; + margin: 2.41em 0 0 1.5em; + border-left:1px solid #d3d6df; + font-size: 0.75em; + line-height: 1.5; +} + +#second-nav ul { + padding:0; + margin:0; + list-style:none; +} + +#second-nav ul ul { + margin-left: 1em; +} + +#second-nav li { + font-weight: normal; + margin:0; + padding:0; +} + +#second-nav p { + line-height: 2; + font-weight: bold; + margin: 0; +} + +#second-nav h2 { + margin:0; +} + + +/* + * Typography + */ + +p { + margin: 1.5em 0 1.5em 0; +} + +strong { + font-weight: bold; +} + +em { + font-style: italic; +} + +h1 +, h2 +, h3 +, h4 +, h5 +, h6 { + font-weight: 600; + color: black; +} +small { + font-size: 0.75em; +} +sup { + font-size: 0.75em; + vertical-align:top; +} +h1 { + line-height: 0.8; + font-weight: normal; + font-size: 1.875em; + margin: 0.8em 0 0.8em 0; +} + +h2 { + font-size: 1.5em; + font-weight: normal; + line-height: 1; + margin: 1em 0 1em 0; +} + +h3 { + font-size: 1.125em; + line-height: 1.333em; + margin: 1.333em 0 0 0; +} + + +h4 { + font-weight: normal; + font-style: italic; + margin: 1.5em 0 1.5em 0; +} + +h5 { + font-style: italic; + font-size: 0.75em; + margin: 2em 0 2em 0; +} + +ol,ul { + padding-left: 1.5em; + margin-left:0; + margin: 1.5em 0 1.5em 0; +} + +ol { + list-style-type: decimal; +} + +ul { + list-style-type: disc; + } + +th { + font-weight: bold; + margin: 1.5em 0 1.5em 0; + } + +hr { + border: none; + background-color: #bbb; + height: 1px; + margin: 1.4375em 0 1.5em 0; +} + +.hidecss { + display: none; +} + +pre { + overflow: auto; +} + +dd { + margin: 0 0 0 1.5em; +} + +.toc { + font-size: 0.75em; + list-style:none; + background-image: url('Pics/greydot.png'); + background-position: bottom left; + background-repeat: repeat-x; + line-height:1.833; + padding: 0; + max-width: 67%; +} + +.toc li { + background-image: url('Pics/greydot.png'); + background-position: top left; + background-repeat: repeat-x; + padding: 0.0833em 0 0.0833em 0; + } + +.toc a { + display:block; + text-decoration: none; +} + +.toc a:hover { + display:block; + background-color: #f0f0f4; + text-decoration: underline; +} + +input:focus { + background-color:#FFFFCB; + +} +/* + * Sitemap + */ + +.card { + clear:both; + margin:1.5em 0 1.5em 0; + background-position: 0 -50px; + background-repeat: repeat-x; + padding:0; +} + +.card ul { + margin:0.5em 0 1em 0; +} + +.card ul li { + list-style:none; +} + +.card h2 { +} + +.lefthalf { + float:left; +} + +.righthalf { + margin-left:50%; +} + +.lefthalf ul { + margin-top:0; +} + +/* + * Footer + */ + +#footer { + font-size: 0.75em; + border: 1px solid #dfdfe0; + border-bottom: 0; + padding:1em; + background-color: #f2f3f6; + margin: 0 0 0 0; + line-height: 1.5em; +} +#footer p { + margin: 1em 0 1em 0; + } + + + +#footer hr { + border-top: 1px solid #d2d3d7; + border-bottom: 1px solid white; + height: 0; +} + +#footer .editbar li { + display: inline; + margin-right: 2em; +} + +#footer .info { +} + +#fineprint { + margin-bottom: 1em; +} + +#footermap { + list-style:none; + margin: 0 0 0 0; + padding: 0; + width:100%; + overflow: hidden; + border: 0; +} + +ul#footermap-cola a +, ul#footermap-colb a +, ul#footermap-colc a +, ul#footermap-cold a +, ul#footermap-cole a { + padding-left: 0; +} + +ul#footermap-cola +, ul#footermap-colb +, ul#footermap-colc +, ul#footermap-cold +, ul#footermap-cole { + float:left; + width: 19%; + min-width: 11em; + height: 12em; /* Update when adding items */ + margin:0 1% 0 0; + padding: 2em 0 0 0; + list-style: none; +} + +ul#footermap-cole { + width: 18.9%; + margin-right:0; +} + +#footermap-wrap { + padding:2em; + border-top: 1px solid white; +} + +#footermap a { + margin: 0; +} + +#footermap ul{ + list-style: none; + padding:0; +} + +#footermap li { + text-indent:0; + background-color: transparent; + font-weight:bold; +} + +#footermap li ul { + margin: 0; + padding: 0: +} + +#footermap li li { + margin:0; + text-indent:0; + padding:0; + font-weight:normal; + border:0; + background-image:none; + background-color:transparent; +} + +#sitetools form { + margin:0; + padding:0; +} + +#sitetools input { + margin: 0 0 0 0.25em; + padding-left: 4px; + padding-right: 4px; +} + +#sitetools select { + margin-left: 0.5em; +} + +#sitetools form p { + display: inline; + line-height: 1; + margin:0; + padding:0; +} + +.sitetool a { + margin: 0.5em 0 0.5em 1em; + padding: 0 0 0 0; + float: left; +} + +.sitetool { + margin:0; + padding: 2px 5px 2px 5px; + border-left: 1px solid white; + border-right: 1px solid #d2d3d7; + display:block; + float:left; +} + +#serverselect input +, #serverselect option +, #serverselect select { +} + +#serverselect ul { + display: inline; + margin-left: 2em; +} + +#serverselect li { + list-style: none; + display: inline; + padding:0 1em 0 1em; + margin:0; +} + +#serverselect form p { + margin:0; + padding:0; + line-height: 1; +} + +.lcol50 { + float: left; + width: 49%; + font-size:0.75em; + margin:0 0 0 0; + padding:0 0.5em 0 0; +} + +.lcol50 h2 { + margin-top:0; +} + +.rcol50 { + margin:0 0 0 51%; + padding:0; + font-size:0.75em; +} + +/* + * Extras + */ + +.clear { + clear:both +} + +#clear { + clear:both; + border:0; + height:1px; + display:block; + } + +.quicklist:before { + content: "Quick Links: "; + font-weight: bold; +} + +.quicklist { + list-style: none; + font-size: 0.75em; + margin:0; + padding:0; + text-indent:0; + line-height: 2em; +} + +.quicklist li { + display:inline; +} + +.item p{ + margin: 0; +} + +.item h2 +, .item p +, .item ul{ + margin-right: 10px +} + +.item h2 { + margin-top: 0; + } + +.col50 { + width:50%; + float: left; +} + +.lastcol { + margin: auto; + width: 50%; + float:left; +} + +.lastcol h2 +, .lastcol p +, .lastcol ul { + margin-left: 10px; + margin-right:0; +} + +.line { +/* clear: both; + display: block; + margin: 0 0 2em 0; + */ + padding: 0; + width: auto; + overflow: hidden; +} + +.cardleft { + width:49%; + float: left; +} + +.cardright { + margin: auto; + width: 50%; + float:left; +} + +.cardleft div { + margin-right: 1.5em; +} +.cardleft h2 { + margin-right: 1em; +} +.cardright div { + margin-left: 1.5em; +} +.cardright h2 { + margin-left: 1em; +} +.votemenu a { + display:block; +} + +table.vote td, table.vote th { + padding-right: 1.5em; + } +} diff --git a/debwiki/css/debwiki.css b/debwiki/css/debwiki.css new file mode 100644 index 0000000..f59c78e --- /dev/null +++ b/debwiki/css/debwiki.css @@ -0,0 +1,527 @@ +/* + * wiki.debian.org stylesheet proposal + * + * Kalle Söderman, 2008 debwiki.css + * + * Copyleft : This work is free, you can copy, spread, and modify it under + * the terms of the Free Art License http://artlibre.org/licence/lal/en/ + * + * + * Font size table + * --------------- + * Browser default 16px + * + * 14px 87.5% body + * 24px 1.714em + * 18px 1.286em + * 16px 1.143em + * 12px 0.857em + * 11px 0.75em + * 8px 0.57em + */ + +@import url("debian.css"); + +/* + * Header + */ +body { + font-size: 100%; +} + +#breadcrumbs { + text-transform: none; +} +#wikisection p.section{ + left: 0; +} +#wikisection { + position: absolute; + top: 0; +} +div#username { + font-size: 0.75em; + margin-left: 5em; + color: #d2d3d7; +} +.sitetools { + text-align:left; + margin: 0 10px 0 0; + padding: 2px 10px 2px 5px; + position: absolute; + top:0; + right:0; + border-right: 1px solid white; + border-left: 1px solid #d2d3d7; + line-height: 1em; +} + +#searchform { + float: left; + font-size: 0.75em; + line-height: 2; +} + +#pagelocation { +} + + +#sitetools form { + margin:0; + padding:0; +} + +#sitetools input { + margin: 0 0 0 0.25em; + padding-left: 4px; + padding-right: 4px; +} + +#sitetools select { + margin-left: 0.5em; +} + +#sitetools form p { + display: inline; + line-height: 1em; + margin:0; + padding:0; +} + +.sitetools a { + margin: 5px 0.5em 2px 0; + padding: 0 0 0 0; +} + +.sitetools { + margin:0; + padding: 2px 10px 2px 5px; + border-left: 1px solid white; + border-right: 1px solid #d2d3d7; + display:block; + float:left; +} + +/* + * Leftcol (Should be renamed secondnav) + */ + +#leftcol { + float: right; + margin: 2em 0 0 1em ; + width: 16em; + clear: both; +} + +#leftcol a { + display: block; +} + +#leftcol #username { + margin: 0 0 1em 0; + display:block; +} + +#userhome { + font-weight: bold; + margin-bottom: 1em; +} + +#navibar +, .editbar { + list-style: none; + margin: 0; + padding:0; +} + +#leftcol ul.editbar { + margin-top: 1em; +} + +form select { +} + +#leftcol .editbar form select { + width: 100%; +} + +.editbar { + background: url('Pics/reddot.png') bottom left repeat-x; + width: 100%; + padding: 0 0 0.5em 0; + font-size: 0.75em; + line-height: 2; +} + +#leftcol li { + display:block; + margin:0; + padding:0; + list-style: none; +} + +#content { + margin-top: 1.5em; +} + +.info { + position: relative; + margin:0 0 0.5em 0; + float: none; +} +#leftcol .info a { + display: inline; +} + +#leftcol .info strong { + margin: 0; + padding: 0; +} + +/* + * Typography + */ + +hr { + background-color: #d2d3d7; + height: 1px; +} + +pre, div.codearea { + padding: 1em; + margin: 2em 1.5em 2em 1.5em; + line-height: 1.5em; + background-color: #f5f6f7; + border: 1px solid #d2d3d7 ; + font-family: monospace; + font-size: 100%; + line-height: 2em; +} +div.codearea pre { + border: none; + padding: 0; + margin: 0; +} +div.table-of-contents { + font-size: 0.75em; + line-height: 2em; + list-style:none; + background-image: url('../img/greydot.png'); + background-position: bottom left; + background-repeat: repeat-x; + background-color: transparent; + padding: 0; + margin:0; + border:0; + max-width: 50em; + display:block; +} + +p.table-of-contents-heading { + font-weight:bold; + padding:0; + margin:1.5em 0 0 0; + font-size: 125%; + letter-spacing: normal; +} + +div.table-of-contents ol { + list-style-position: inside; + padding:0; + margin: 0; +} + +div.table-of-contents ol ol { + list-style-position: inside; + padding-left: 2em; + margin: 0; +} + + +div.table-of-contents li { + background-image: url('../img/greydot.png'); + background-position: top left; + background-repeat: repeat-x; + padding: 0; + margin:0; + } + +div.table-of-contents a:hover { + background-color: #f0f0f4; +} + +div.table-of-contents a { + text-decoration: none; +} + +.portal h1 { + margin-top: 0; + line-height: 1em; +} + +.portal h1:after { + content: "Portal"; + font-family:monospace; + font-weight: normal; + font-size: 0.62em; + text-transform: uppercase; + letter-spacing: 0.08em; + background-color: #c70036; + line-height: 16px; + color:white; + padding: 0 5px 0 5px; + margin:1em 0 3em 0; + display: block; +} +h1#locationline { + margin-bottom: 0.5em; +} +h1#locationline a { + color: black; +} +span.u { + font-style: normal; + font-weight: normal; + text-decoration: underline; +} +p.searchhint { + padding:1em; + border: 1px solid #cccca3; + margin:1em 0 1em 0; + background-color:#ffffcb; + font-size: 0.75em; + line-height: 2; +} +p.searchstats { + font-size: 0.75em; + background-color: transparent; + background-color: #f5f6f7; + margin:0; + border-top: 1px solid #d2d3d7 ; + text-transform:lowercase; + line-height: 2; + padding: 0; +} +div.codearea { + margin: 2em 1.5em 2em 1.5em; + font-family: monospace; +} +a.codenumbers { + font-size: 100%; +} + + +/* + * Footer + */ + +p#pageinfo { + color: gray; + font-size: 0.75em; + margin: 1em 0 0 62px; +} + +#footer { + margin-top: 2em; + margin-left: 61px; + margin-right: 10px; + clear: both; +} +#footer ul.editbar { + font-size: 1em; + border-bottom: 1px solid #d2d3d7; + background-image: none; + margin: 0 0 1.5em 0; +} + +ul#credits { + margin: 1em 0 0 0; + padding:0; + font-size: 1em; + line-height: 2; +} + +ul#credits li { + list-style: none; + display: inline; + margin: 0 1em 0 0; +} + +#content div.caution +, #content div.important +, #content div.note +, #content div.tip +, #content div.warning { + margin: 1em 0 1em 0; +} + +#message { + background-color: #f5f6f7; + padding: 1em; + margin: 1em 0 1em 0; + border: 1px solid #d2d3d7 ; + font-size: 0.75em; + line-height: 2; +} + +#message p { + margin:0; + padding:0; +} + +table { + margin: 0.75em 0 0.75em 0; +} +td { + padding: 0 1em 0 0.5em; +} + +#content div.debian { + border:1px solid #c70036; + border-top: 1px solid #c70036; + background-repeat: no-repeat; + background-position: 10px 5px; + margin: 2em 1.5em 2em 1.5em; + padding: 0 1.5em 0 50px; + font-size: 0.75em; +} +#content div.debian p { + margin: 1.5em 0 1.5em 0; +} + +/* + * Editor + */ + +#editor #editor-textarea { + display: block; + margin: 1em 0 1em 0; +} +p img.attachment { + float: left; + padding-right: 1.5em; +} +table p img.attachment { + display: inline; + float: none; + padding: 0; +} +p img { + display: inline; +} +table.diff { + font-family: monospace; + font-size: 1em; +} +div#header ul li { + display: inline; + margin-right: 1em; +} +ul#navibar li.wikilink { + margin: 0; +} +ul#navibar li.current { + display: none; +} +li.wikilink { + margin:0; + padding:0; +} +ul#navibar li.userlink { + margin:0; + padding:0; +} +#pagetrail { + margin:0; + font-size: 0.75em; + text-transform: lowercase; + line-height: 2; + background-color: transparent; + background-color: #f5f6f7; + border-bottom: 1px solid #d2d3d7 ; + min-height: 20px; +} +#pagetrail:before { + content: "/"; + margin-left: 0.5em; + margin-right: 0.5em; +} +#searchform { + position: absolute; + right: 10px; + top: 0; +} +div#content { + margin: 0 10px 0 61px; +} +div#header { + margin:0; +} +#navbar { + background-color: transparent; + list-style:none; + display:block; + border-bottom:1px solid #c70036; + text-indent:0; + padding: 0; + margin-top:0; + margin-bottom:0; +} +#navbar ul { + margin: 0; + padding: 0; + clear: both; + overflow: hidden; + min-height: 45px; +} +#navbar li { + list-style: none; + float: left; + padding: 0; + margin: 0; +} +#navbar a:link +, #navbar a:visited { + padding: 1.75em 1em 0.25em 1em; + border-left: 1px solid transparent; + border-right: 1px solid transparent; + display: block; + text-decoration: none; +} +#navbar a:visited { + color: #54638c; +} +#navbar a:hover +, #navbar a:visited:hover { + background-color: #efefef; + border-left: 1px solid #d2d3d7; + border-right: 1px solid #d2d3d7; + text-decoration: underline; +} +form.actionsmenu { + float: right; + vertical-align: text-top; +} +span.sep { + margin-right: 0.5em; + margin-left: 0.5em; +} +td.diff-added { + color: #31a300; +} +td.diff-removed { + color: #c70036; +} +div#domaintools { + position: absolute; + top: 0; + left: 0; +} +div#domaintools p.section { + margin: 0; +} +div#domaintools div#username { + line-height: 1.5em; + margin-left: 10em; + top:0; +} diff --git a/debwiki/css/modernized-common.css b/debwiki/css/modernized-common.css new file mode 100644 index 0000000..e3cdb42 --- /dev/null +++ b/debwiki/css/modernized-common.css @@ -0,0 +1,545 @@ +/* common.css - MoinMoin Default Styles + +Copyright (c) 2001, 2002, 2003 by Juergen Hermann +*/ + +/* content styles */ + +html { + background-color: white; + color: black; + font-family: sans-serif; + font-size: 1em; +} + +body { + margin: 0; +} + +/* Links */ + +a {color: #0044B3;} +/* a:visited {color: #597BB3;} */ +a:visited {color: #FF7BB3;} + +a.nonexistent:visited, a.nonexistent, +a.badinterwiki:visited, a.badinterwiki {color: gray;} + +a.www:before {content: url(../img/moin-www.png); margin: 0 0.2em;} +a.http:before {content: url(../img/moin-www.png); margin: 0 0.2em;} +a.https:before {content: url(../img/moin-www.png); margin: 0 0.2em;} +a.file:before {content: url(../img/moin-ftp.png); margin: 0 0.2em;} +a.ftp:before {content: url(../img/moin-ftp.png); margin: 0 0.2em;} +a.nntp:before {content: url(../img/moin-news.png); margin: 0 0.2em;} +a.news:before {content: url(../img/moin-news.png); margin: 0 0.2em;} +a.telnet:before, a.ssh:before {content: url(../img/moin-telnet.png); margin: 0 0.2em;} +a.irc:before, a.ircs:before {content: url(../img/moin-telnet.png); margin: 0 0.2em;} +a.mailto:before {content: url(../img/moin-email.png); margin: 0 0.2em;} +a.attachment:before {content: url(../img/moin-attach.png); margin: 0 0.2em;} +a.badinterwiki:before {content: url(../img/moin-inter.png); margin: 0 0.2em;} +a.interwiki:before {content: url(../img/moin-inter.png); margin: 0 0.2em;} + +li p { + margin: .25em 0; +} + +li.gap { + margin-top: 0.5em; +} + +dt { + margin-top: 0.5em; + font-weight: bold; +} + +dd { + margin-top: 0; + margin-bottom: 0; +} + +dd p { + margin: 0.25em 0; +} + +a, img, img.drawing { + border: 0; +} + +pre { + border: 1pt solid #AEBDCC; + background-color: #F3F5F7; + padding: 5pt; + font-family: courier, monospace; + white-space: pre; + /* begin css 3 or browser specific rules - do not remove! + see: http://forums.techguy.org/archive/index.php/t-249849.html */ + white-space: pre-wrap; + word-wrap: break-word; + white-space: -moz-pre-wrap; + white-space: -pre-wrap; + white-space: -o-pre-wrap; + /* end css 3 or browser specific rules */ +} + +pre.comment { + background-color: #CCCCCC; + color: red; + padding: 0; + margin: 0; + border: 0; +} + +pre.comment:before { + content: url(../img/attention.png); +} + + +/* .comment css definition must be top of .red/.green/.blue or it won't work */ +.comment { color: #555555; background-color: #DDDDFF; } + +.red { background-color: #FFCCCC; } +.green { background-color: #CCFFCC; } +.blue { background-color: #CCCCFF; } +.yellow { background-color: #FFF29F; } +.orange { background-color: #FFD59B; } + +.solid { border: 2px solid #000000; padding: 2px; } +.dashed { border: 2px dashed #000000; padding: 2px; } +.dotted { border: 2px dotted #000000; padding: 2px; } + +.left { text-align: left; } +.center { text-align: center; } +.right { text-align: right; } +.justify { text-align: justify; } + +table +{ + margin: 0.5em 0 0 0.5em; + border-collapse: collapse; +} + +th, td +{ + padding: 0.25em 0.5em 0.25em 0.5em; + border: 1pt solid #ADB9CC; +} + +td p { + margin: 0; + padding: 0; +} +/* TableOfContents macro */ +div.table-of-contents { + border: 1px solid #bbbbbb; + color: black; + background-color: #eeeeee; + font-size: 80%; + text-align: left; + margin: 0.5em 0 0.5em 1em; + padding: 0.5em 0.75em 0.5em 0.5em; + max-width: 50%; + display: inline-table; +} +div.table-of-contents ol { + margin: 0; + padding: 0 0 0 2em; +} +div.table-of-contents ul { + margin: 0; + list-style:none; +} +div.table-of-contents li { + margin:0; + padding: 0; +} +p.table-of-contents-heading { + font-weight:bold; + padding:0; + margin: 0 0 0.5em 0; + letter-spacing: 0.075em; +} + +/* Navigation macro */ +table.navigation { + background: #fff; + margin: 0; +} + +.footnotes div { + width: 5em; + border-top: 1pt solid gray; +} + +.footnotes ol { + padding: 0 2em; + margin: 0 0 1em; +} + +.footnotes li { +} + +.info { + float: right; + font-size: 0.7em; + color: gray; +} + +#pageinfo { + margin-top: 2em; +} + +.seperator { + color: gray; +} + +#pagebottom {clear: both;} + +/* standard rule ---- */ +hr { + height: 1pt; + background-color: #9C9C9C; + border: 0; +} + +/* custom rules ----- to ---------- */ +.hr1 {height: 2pt;} +.hr2 {height: 3pt;} +.hr3 {height: 4pt;} +.hr4 {height: 5pt;} +.hr5 {height: 6pt;} +.hr6 {height: 7pt;} + +/* Replacement for deprecated html 3 element and html 4 */ +.u {text-decoration: underline;} +.strike {text-decoration: line-through;} + +/* eye catchers */ +.warning +{ + color: red; +} + +.error +{ + color: red; +} + +strong.highlight +{ + background-color: #CCE0FF; + padding: 1pt; +} + + +/* Recent changes */ + +.rcrss { + float: right; + margin: 0 7px 0 14px; + height: 0; + position: relative; + top: 9px; +} +*[div="rtl"] .rcrss { + float: left; +} +.recentchanges[dir="rtl"] .rcrss { + float: left; +} + +.recentchanges table { + clear: both; + border-collapse: collapse; + + border: 1px solid #4d7da9; +} + +.recentchanges td { + vertical-align: top; + border: none; + background: #e6eaf0; +} + + +.recentchanges .rcdaybreak td { + background: #81BBF2; + border: none; + border: 1px solid #4d7da9; +} + +.rcdaybreak td a { + font-size: 0.88em; +} + +.rcicon1, .rcicon2 { + text-align: center; +} + +.rcpagelink { + width: 33%; +} + +.rctime { + font-size: 0.88em; + white-space: nowrap; +} + +.rceditor { + white-space: nowrap; + font-size: 0.88em; +} + +.rccomment { + width: 50%; + color: gray; + font-size: 0.88em; +} + + +/* User Preferences */ + +.userpref table, .userpref td { + border: none; +} + +/* CSS for new code_area markup used by Colorizer and ParserBase */ + +div.codearea { /* the div makes the border */ + margin: 0.5em 0; + padding: 0; + border: 1pt solid #AEBDCC; + background-color: #F3F5F7; + color: black; +} + +div.codearea pre { /* the pre has no border and is inside the div */ + margin: 0; + padding: 10pt; + border: none; +} + +a.codenumbers { /* format of the line numbering link */ + margin: 0 10pt; + font-size: 0.85em; + color: gray; +} + +/* format of certain syntax spans */ +div.codearea pre span.LineNumber {color: gray;} +div.codearea pre span.ID {color: #000000;} +div.codearea pre span.Operator {color: #0000C0;} +div.codearea pre span.Char {color: #004080;} +div.codearea pre span.Comment {color: #008000;} +div.codearea pre span.Number {color: #0080C0;} +div.codearea pre span.String {color: #004080;} +div.codearea pre span.SPChar {color: #0000C0;} +div.codearea pre span.ResWord {color: #A00000;} +div.codearea pre span.ConsWord {color: #008080; font-weight: bold;} +div.codearea pre span.Error {color: #FF8080; border: solid 1.5pt #FF0000;} +div.codearea pre span.ResWord2 {color: #0080ff; font-weight: bold;} +div.codearea pre span.Special {color: #0000ff;} +div.codearea pre span.Preprc {color: #803999;} + +/* for diff parser */ +div.codearea pre span.DiffAdded {color: #4876FF;} +div.codearea pre span.DiffRemoved {color: #FF0000;} +div.codearea pre span.DiffChanged {color: #FF7F50;} +div.codearea pre span.DiffSeparator {color: #228B22; font-weight: bold} + +/* Search results */ +.advancedsearch { + border: 1pt solid #ADB9CC; +} + +.advancedsearch td { + vertical-align: top; + background-color: #E7E7E7; + border: 0px; +} + +.advancedsearch td.searchfor { + font-weight: bold; +} + +.advancedsearch input { + border: 1px solid #ADB9CC; + background-color: #fff; +} + +.advancedsearch input[disabled] { + background-color: #eee; +} + +.advancedsearch td.submit { + border-top: 1px solid #ADB9CC; + background-color: #fff; + text-align: right; +} + +.advancedsearch optioni, +.advancedsearch select { + border: 1px solid #ADB9CC; + background-color: #fff; +} + + +.searchresults dt { + margin-top: 1em; + font-weight: normal; +} + +.searchresults dd, .searchresults p { + font-size: 0.85em; +} + +.searchresults .searchhitinfobar { + color: #008000; + margin-left: 15px; + margin-top: 0; +} + +p.searchstats { + font-size: 0.8em; + text-align: right; + width: 100%; + background-color: #E6EAF0; + border-top: 1px solid #9088DC; + padding: 2px; +} + +p.searchhint { + background-color: #E6EAF0; + border: 1px solid #9088DC; + padding: 2px; +} + +.searchpages { + margin-left: auto; + margin-right: auto; +} + +.searchpages tr, .searchpages td { + border: 0; + padding: 5px; + margin: 0; + text-align: center; + vertical-align: middle; + color: #b93a58; + font-weight: bold; + font-size: 1.05em; +} + +.searchpages td a, .searchpages td a:link { + text-decoration: underline; +} + +/* MonthCalendar css */ + +/* days without and with pages linked to them */ +a.cal-emptyday { + color: #777777; + text-align: center; +} +a.cal-usedday { + color: #000000; + font-weight: bold; + text-align: center; +} +/* general stuff: workdays, weekend, today */ +td.cal-workday { + background-color: #DDDDFF; + text-align: center; +} +td.cal-weekend { + background-color: #FFDDDD; + text-align: center; +} +td.cal-today { + background-color: #CCFFCC; + border-style: solid; + border-width: 2pt; + text-align: center; +} +/* invalid places on the monthly calendar sheet */ +td.cal-invalidday { + background-color: #CCCCCC; +} +/* links to prev/next month/year */ +a.cal-link { + color: #000000; + text-decoration: none; +} +th.cal-header { + background-color: #DDBBFF; + text-align: center; +} + +/* for MonthCalendar mouseover info boxes */ +TABLE.tip { + color: black; + background-color: #FF8888; + font-size: small; + font-weight: normal; + border-style: solid; + border-width: 1px; +} + +TH.tip { + background-color: #FF4444; + font-weight: bold; + text-align: center; +} + +TD.tip { + text-align: left; +} +*[dir="rtl"] TD.tip { + text-align: right; +} + +/* end MonthCalendar stuff */ + +#message .hint {font-style: italic;} +#message .info { + float: none; + font-size: 1em; + color: black; +} +#message .info:before {content: url('../img/icon-info.png'); margin: 0 0.2em;} +#message .warning:before {content: url('../img/alert.png'); margin: 0 0.2em;} +#message .error:before {content: url('../img/icon-error.png'); margin: 0 0.2em;} + + +/* admonition start */ +#content div.caution, +#content div.important, +#content div.note, +#content div.tip, +#content div.warning { + border: 1pt solid #E5E5E5; + background-color: #F9F9FF; + color: black; + + margin: 10pt 30pt 10pt 30pt; + background-repeat: no-repeat; + background-position: 8px 8px; + min-height: 64px; /*64=48+8+8 but doesn't work with IE*/ + padding-left: 64px; +} + +#content div.caution p, +#content div.important p, +#content div.note p, +#content div.tip p, +#content div.warning p { + margin-top: 8px; /*to align text with bg graphic*/ +} + +#content div.tip { background-image: url("../img/admon-tip.png"); } +#content div.note { background-image: url("../img/admon-note.png"); } +#content div.important { background-image: url("../img/admon-important.png"); } +#content div.caution { background-image: url("../img/admon-caution.png"); } +#content div.warning { background-image: url("../img/admon-warning.png"); } + +/* admonition end */ + diff --git a/debwiki/css/msie.css b/debwiki/css/msie.css new file mode 100644 index 0000000..6aea986 --- /dev/null +++ b/debwiki/css/msie.css @@ -0,0 +1,37 @@ +/* msie.css - MoinMoin MS Internet explorer bug workarounds */ + +/* IE6 and IE7 both suck with :before */ +a.www { padding-left: 19px; background: url(../img/moin-www.png) left center no-repeat; } +a.http { padding-left: 19px; background: url(../img/moin-www.png) left center no-repeat; } +a.https { padding-left: 19px; background: url(../img/moin-www.png) left center no-repeat; } +a.file { padding-left: 19px; background: url(../img/moin-ftp.png) left center no-repeat; } +a.ftp { padding-left: 19px; background: url(../img/moin-ftp.png) left center no-repeat; } +a.nntp { padding-left: 19px; background: url(../img/moin-news.png) left center no-repeat; } +a.news { padding-left: 19px; background: url(../img/moin-news.png) left center no-repeat; } +a.telnet, a.ssh { padding-left: 19px; background: url(../img/moin-telnet.png) left center no-repeat; } +a.irc, a.ircs { padding-left: 19px; background: url(../img/moin-telnet.png) left center no-repeat; } +a.mailto { padding-left: 19px; background: url(../img/moin-email.png) left center no-repeat; } +a.attachment { padding-left: 19px; background: url(../img/moin-attach.png) left center no-repeat; } +a.badinterwiki { padding-left: 19px; background: url(../img/moin-inter.png) left center no-repeat; } +a.interwiki { padding-left: 19px; background: url(../img/moin-inter.png) left center no-repeat; } +#message .warning { padding-left: 21px; background: url(../img/alert.png) left center no-repeat; } +#message .error { padding-left: 21px; background: url(../img/icon-error.png) left center no-repeat; } + +#pagetrail li, #pagelocation li { + border-left: 1px solid #AAA; + padding: 0 0.3em; +} + +/* Spans for line-anchors - needed for IE6 and IE7 where omitting the "display: none" triggers rendering bugs. */ +span.anchor { display: none; } + +/* Some * html hacks for IE6 and below only (IE7 ignores * html) */ + +/* IE6 has a bug with rendering of float elements. We workaround this bug by + * assigning those elements a height attribute because we currently don't know + * a better solution. This results in IE calculating the correct height of the + * characters and displaying them correctly. We don't know any negative side + * effects of this workaround: + */ +* html div#page, * html div#header { height: 0.001%; } + diff --git a/debwiki/css/print.css b/debwiki/css/print.css new file mode 100644 index 0000000..bab9a12 --- /dev/null +++ b/debwiki/css/print.css @@ -0,0 +1,52 @@ +/* print.css - MoinMoin Default Styles + +Copyright (c) 2001, 2002, 2003 by Juergen Hermann +*/ + +/* content styles */ + +html { + font-family: Times, serif; + font-size: 12pt; +} + +body { + /* Give about 3.4cm in Mozilla/Firefox and about 2.2cm in Safari */ + margin: 1.5cm; +} + +a, a:visited, a.nonexistent, a.badinterwiki { + color: black; + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +.info a { + color: gray; +} + +pre { + font-size: 10pt; +} + +a.interwiki:before, a.badinterwiki:before { + content: attr(title) ":"; +} + +a.interwiki img, a.badinterwiki img { + display: none; +} + +.footnotes div { + border-top: 1pt solid gray; +} + +/* user interface styles */ + +#header, #sidebar, #footer, #timings, #credits, #interwiki, #pagelocation { + display: none; +} + diff --git a/debwiki/css/projection.css b/debwiki/css/projection.css new file mode 100644 index 0000000..627093e --- /dev/null +++ b/debwiki/css/projection.css @@ -0,0 +1,33 @@ +/* projection.css - MoinMoin Slide Styles + +Copyright (c) 2003 by Juergen Hermann +*/ + +@import url(screen.css); + +html { line-height: 1.8em; } + +body, b, em, a, span, div, p, td { font-size: 18pt; } + +h1 { font-size: 26pt; } +h2 { font-size: 22pt; } +h3 { font-size: 20pt; } +h4 { font-size: 18pt; } +h5 { font-size: 16pt; } +h6 { font-size: 14pt; } + +tt, pre { font-size: 16pt; } +sup, sub { font-size: 12pt; } + +table.navigation { + float: right; + margin: 2px; +} + +.navigation td, .navigation a { + font-size: 10pt; + padding: 2px; +} + +#interwiki, #pagelocation, #pageinfo { display: none; } + diff --git a/debwiki/css/screen.css b/debwiki/css/screen.css new file mode 100644 index 0000000..4c12486 --- /dev/null +++ b/debwiki/css/screen.css @@ -0,0 +1,135 @@ +/* + * www.debian.org redesign + * + * Kalle Soderman, 2008 debhome.css + * + * Copyleft : This work is free, you can copy, spread, and modify it under + * the terms of the Free Art License http://artlibre.org/licence/lal/en/ + */ +/* + @import url("debheld.css") handheld; +@import url("debian.css") screen; +@import url("debscreen.css) screen; +*/ + +#splash { + margin-top:0px; + margin-bottom: 1em; + text-align:center; + overflow:hidden; + height: 150px; +} +#splash h1 { + background-image: url('Pics/debian-61_glossy-large.png'); + background-position:top center; + padding-top:190px; + overflow:hidden; + text-align:center; + background-repeat:no-repeat; + display:block; + margin:0; + height:0; +} +#maincol { + background-image: url('Pics/cropped-swirls.png'); + background-position:top center; + background-repeat: repeat-x; +} +#announce { + text-align: center; + float: left; + width: 41%; + min-width: 260px; + margin-bottom: 1.5em; +} +#intro { + padding-top: 0; +} +#intro p { + margin-top: 0em; + padding:0; +} +#hometoc { + list-style:none; + margin: 0 0 2em 0; + padding: 0; + width:100%; + font-size: 0.75em; + overflow: hidden; + line-height: 1.5em; + border: 0; +} +#hometoc a { + text-decoration: none; +} +#hometoc a:hover { + text-decoration: underline; +} +ul#hometoc-cola a, ul#hometoc-colb a, ul#hometoc-colc a, ul#hometoc-cold a, ul#hometoc-cole a { + padding-left: 5px; +} +ul#hometoc-cola, ul#hometoc-colb,ul#hometoc-colc, ul#hometoc-cold, ul#hometoc-cole { + float:left; + width: 19.2%; + min-width: 11em; + height: 14em; /* Update when adding items */ + margin:0 1% 0 0; + padding: 0; + background-image:url('Pics/gradient.png'); + background-position: 0 -40px; + background-repeat: repeat-x; +/* border-top: 2px solid #c6c8e0; + border-bottom: 1px solid #c6c8e0; +*/ + border-top: 1px solid #c6c8e0; + list-style: none; +} +ul#hometoc-cole { + width: 18.9%; + margin-right:0; +} +#hometoc-wrap { + padding:1em 1em 1em 1em; + border-top: 1px solid white; +} +#hometoc a { + margin: 0; +} +#hometoc ul{ + list-style: none; + padding: 1em 0 0 0; +} +#hometoc ul ul { + padding: 0; +} +#hometoc li { + text-indent:0; + background-color: transparent; + font-weight:bold; +} +#hometoc li ul { + margin: 0; + padding: 0: + +} +#hometoc li li { + margin:0; + text-indent:0; + padding:0; + font-weight:normal; + border:0; + background-image:none; + background-color:transparent; +} +.infobar { + margin: 0 0 2em 0; + padding: 1em 5px 1em 5px; + line-height: 1em; + font-size: 0.75em; + border: 1px solid #d2d3d7; + border-bottom: 1px solid #d2d3d7; + background-image:url('Pics/gradient.png'); + background-position: 0 -35px; + background-repeat: repeat-x; + clear: both; +} diff --git a/debwiki/img/PythonPowered.png b/debwiki/img/PythonPowered.png new file mode 100644 index 0000000..d9d9e6f Binary files /dev/null and b/debwiki/img/PythonPowered.png differ diff --git a/debwiki/img/admon-caution.png b/debwiki/img/admon-caution.png new file mode 100644 index 0000000..750ae97 Binary files /dev/null and b/debwiki/img/admon-caution.png differ diff --git a/debwiki/img/admon-important.png b/debwiki/img/admon-important.png new file mode 100644 index 0000000..c5726d5 Binary files /dev/null and b/debwiki/img/admon-important.png differ diff --git a/debwiki/img/admon-note.png b/debwiki/img/admon-note.png new file mode 100644 index 0000000..d01b8c6 Binary files /dev/null and b/debwiki/img/admon-note.png differ diff --git a/debwiki/img/admon-tip.png b/debwiki/img/admon-tip.png new file mode 100644 index 0000000..2ac5747 Binary files /dev/null and b/debwiki/img/admon-tip.png differ diff --git a/debwiki/img/admon-warning.png b/debwiki/img/admon-warning.png new file mode 100644 index 0000000..f5c7a6f Binary files /dev/null and b/debwiki/img/admon-warning.png differ diff --git a/debwiki/img/alert.png b/debwiki/img/alert.png new file mode 100644 index 0000000..06148e8 Binary files /dev/null and b/debwiki/img/alert.png differ diff --git a/debwiki/img/angry.png b/debwiki/img/angry.png new file mode 100644 index 0000000..1189598 Binary files /dev/null and b/debwiki/img/angry.png differ diff --git a/debwiki/img/attach.png b/debwiki/img/attach.png new file mode 100644 index 0000000..9a34c9a Binary files /dev/null and b/debwiki/img/attach.png differ diff --git a/debwiki/img/attention.png b/debwiki/img/attention.png new file mode 100644 index 0000000..b9704e6 Binary files /dev/null and b/debwiki/img/attention.png differ diff --git a/debwiki/img/biggrin.png b/debwiki/img/biggrin.png new file mode 100644 index 0000000..8519e02 Binary files /dev/null and b/debwiki/img/biggrin.png differ diff --git a/debwiki/img/checkmark.png b/debwiki/img/checkmark.png new file mode 100644 index 0000000..2fd3819 Binary files /dev/null and b/debwiki/img/checkmark.png differ diff --git a/debwiki/img/debian-61.png b/debwiki/img/debian-61.png new file mode 100644 index 0000000..6c1c08c Binary files /dev/null and b/debwiki/img/debian-61.png differ diff --git a/debwiki/img/devil.png b/debwiki/img/devil.png new file mode 100644 index 0000000..1fa14fa Binary files /dev/null and b/debwiki/img/devil.png differ diff --git a/debwiki/img/draft.png b/debwiki/img/draft.png new file mode 100644 index 0000000..6b625f4 Binary files /dev/null and b/debwiki/img/draft.png differ diff --git a/debwiki/img/frown.png b/debwiki/img/frown.png new file mode 100644 index 0000000..0f05f25 Binary files /dev/null and b/debwiki/img/frown.png differ diff --git a/debwiki/img/gradient.png b/debwiki/img/gradient.png new file mode 100644 index 0000000..fe633b7 Binary files /dev/null and b/debwiki/img/gradient.png differ diff --git a/debwiki/img/greydot.png b/debwiki/img/greydot.png new file mode 100644 index 0000000..ec23c01 Binary files /dev/null and b/debwiki/img/greydot.png differ diff --git a/debwiki/img/icon-device-32x32.png b/debwiki/img/icon-device-32x32.png new file mode 100644 index 0000000..b3facf7 Binary files /dev/null and b/debwiki/img/icon-device-32x32.png differ diff --git a/debwiki/img/icon-error.png b/debwiki/img/icon-error.png new file mode 100644 index 0000000..ab6808f Binary files /dev/null and b/debwiki/img/icon-error.png differ diff --git a/debwiki/img/icon-info.png b/debwiki/img/icon-info.png new file mode 100644 index 0000000..e8fbc66 Binary files /dev/null and b/debwiki/img/icon-info.png differ diff --git a/debwiki/img/idea.png b/debwiki/img/idea.png new file mode 100644 index 0000000..8eeebdd Binary files /dev/null and b/debwiki/img/idea.png differ diff --git a/debwiki/img/moin-attach.png b/debwiki/img/moin-attach.png new file mode 100644 index 0000000..e9199b0 Binary files /dev/null and b/debwiki/img/moin-attach.png differ diff --git a/debwiki/img/moin-bottom.png b/debwiki/img/moin-bottom.png new file mode 100644 index 0000000..f4014f3 Binary files /dev/null and b/debwiki/img/moin-bottom.png differ diff --git a/debwiki/img/moin-conflict.png b/debwiki/img/moin-conflict.png new file mode 100644 index 0000000..d7cffa5 Binary files /dev/null and b/debwiki/img/moin-conflict.png differ diff --git a/debwiki/img/moin-deleted.png b/debwiki/img/moin-deleted.png new file mode 100644 index 0000000..0532937 Binary files /dev/null and b/debwiki/img/moin-deleted.png differ diff --git a/debwiki/img/moin-diff.png b/debwiki/img/moin-diff.png new file mode 100644 index 0000000..283843d Binary files /dev/null and b/debwiki/img/moin-diff.png differ diff --git a/debwiki/img/moin-download.png b/debwiki/img/moin-download.png new file mode 100644 index 0000000..875c55d Binary files /dev/null and b/debwiki/img/moin-download.png differ diff --git a/debwiki/img/moin-edit.png b/debwiki/img/moin-edit.png new file mode 100644 index 0000000..d926dd4 Binary files /dev/null and b/debwiki/img/moin-edit.png differ diff --git a/debwiki/img/moin-email.png b/debwiki/img/moin-email.png new file mode 100644 index 0000000..9be90c6 Binary files /dev/null and b/debwiki/img/moin-email.png differ diff --git a/debwiki/img/moin-ftp.png b/debwiki/img/moin-ftp.png new file mode 100644 index 0000000..18b7d24 Binary files /dev/null and b/debwiki/img/moin-ftp.png differ diff --git a/debwiki/img/moin-help.png b/debwiki/img/moin-help.png new file mode 100644 index 0000000..61cd256 Binary files /dev/null and b/debwiki/img/moin-help.png differ diff --git a/debwiki/img/moin-home.png b/debwiki/img/moin-home.png new file mode 100644 index 0000000..a0f8f21 Binary files /dev/null and b/debwiki/img/moin-home.png differ diff --git a/debwiki/img/moin-icon.png b/debwiki/img/moin-icon.png new file mode 100644 index 0000000..a644f24 Binary files /dev/null and b/debwiki/img/moin-icon.png differ diff --git a/debwiki/img/moin-info.png b/debwiki/img/moin-info.png new file mode 100644 index 0000000..ef68f64 Binary files /dev/null and b/debwiki/img/moin-info.png differ diff --git a/debwiki/img/moin-inter.png b/debwiki/img/moin-inter.png new file mode 100644 index 0000000..010a249 Binary files /dev/null and b/debwiki/img/moin-inter.png differ diff --git a/debwiki/img/moin-jabber.png b/debwiki/img/moin-jabber.png new file mode 100644 index 0000000..f6e8325 Binary files /dev/null and b/debwiki/img/moin-jabber.png differ diff --git a/debwiki/img/moin-new.png b/debwiki/img/moin-new.png new file mode 100644 index 0000000..522fc34 Binary files /dev/null and b/debwiki/img/moin-new.png differ diff --git a/debwiki/img/moin-news.png b/debwiki/img/moin-news.png new file mode 100644 index 0000000..a9850ee Binary files /dev/null and b/debwiki/img/moin-news.png differ diff --git a/debwiki/img/moin-parent.png b/debwiki/img/moin-parent.png new file mode 100644 index 0000000..590234a Binary files /dev/null and b/debwiki/img/moin-parent.png differ diff --git a/debwiki/img/moin-print.png b/debwiki/img/moin-print.png new file mode 100644 index 0000000..93be1b1 Binary files /dev/null and b/debwiki/img/moin-print.png differ diff --git a/debwiki/img/moin-raw.png b/debwiki/img/moin-raw.png new file mode 100644 index 0000000..2cbcc71 Binary files /dev/null and b/debwiki/img/moin-raw.png differ diff --git a/debwiki/img/moin-readonly.png b/debwiki/img/moin-readonly.png new file mode 100644 index 0000000..0466619 Binary files /dev/null and b/debwiki/img/moin-readonly.png differ diff --git a/debwiki/img/moin-renamed.png b/debwiki/img/moin-renamed.png new file mode 100644 index 0000000..124d375 Binary files /dev/null and b/debwiki/img/moin-renamed.png differ diff --git a/debwiki/img/moin-rss.png b/debwiki/img/moin-rss.png new file mode 100644 index 0000000..32272be Binary files /dev/null and b/debwiki/img/moin-rss.png differ diff --git a/debwiki/img/moin-search.png b/debwiki/img/moin-search.png new file mode 100644 index 0000000..fd7f0b0 Binary files /dev/null and b/debwiki/img/moin-search.png differ diff --git a/debwiki/img/moin-show.png b/debwiki/img/moin-show.png new file mode 100644 index 0000000..613f136 Binary files /dev/null and b/debwiki/img/moin-show.png differ diff --git a/debwiki/img/moin-subscribe.png b/debwiki/img/moin-subscribe.png new file mode 100644 index 0000000..33e6e31 Binary files /dev/null and b/debwiki/img/moin-subscribe.png differ diff --git a/debwiki/img/moin-telnet.png b/debwiki/img/moin-telnet.png new file mode 100644 index 0000000..619db11 Binary files /dev/null and b/debwiki/img/moin-telnet.png differ diff --git a/debwiki/img/moin-top.png b/debwiki/img/moin-top.png new file mode 100644 index 0000000..314ae47 Binary files /dev/null and b/debwiki/img/moin-top.png differ diff --git a/debwiki/img/moin-unsubscribe.png b/debwiki/img/moin-unsubscribe.png new file mode 100644 index 0000000..9e24ce2 Binary files /dev/null and b/debwiki/img/moin-unsubscribe.png differ diff --git a/debwiki/img/moin-up.png b/debwiki/img/moin-up.png new file mode 100644 index 0000000..5c00095 Binary files /dev/null and b/debwiki/img/moin-up.png differ diff --git a/debwiki/img/moin-updated.png b/debwiki/img/moin-updated.png new file mode 100644 index 0000000..38b1e10 Binary files /dev/null and b/debwiki/img/moin-updated.png differ diff --git a/debwiki/img/moin-www.png b/debwiki/img/moin-www.png new file mode 100644 index 0000000..ac5957a Binary files /dev/null and b/debwiki/img/moin-www.png differ diff --git a/debwiki/img/officiallogo.png b/debwiki/img/officiallogo.png new file mode 100644 index 0000000..4f1b497 Binary files /dev/null and b/debwiki/img/officiallogo.png differ diff --git a/debwiki/img/ohwell.png b/debwiki/img/ohwell.png new file mode 100644 index 0000000..e35daf1 Binary files /dev/null and b/debwiki/img/ohwell.png differ diff --git a/debwiki/img/openlogo-50.png b/debwiki/img/openlogo-50.png new file mode 100644 index 0000000..f4e75fc Binary files /dev/null and b/debwiki/img/openlogo-50.png differ diff --git a/debwiki/img/prio1.png b/debwiki/img/prio1.png new file mode 100644 index 0000000..296fcaa Binary files /dev/null and b/debwiki/img/prio1.png differ diff --git a/debwiki/img/prio2.png b/debwiki/img/prio2.png new file mode 100644 index 0000000..850965c Binary files /dev/null and b/debwiki/img/prio2.png differ diff --git a/debwiki/img/prio3.png b/debwiki/img/prio3.png new file mode 100644 index 0000000..0649d2a Binary files /dev/null and b/debwiki/img/prio3.png differ diff --git a/debwiki/img/redface.png b/debwiki/img/redface.png new file mode 100644 index 0000000..2ea4da9 Binary files /dev/null and b/debwiki/img/redface.png differ diff --git a/debwiki/img/sad.png b/debwiki/img/sad.png new file mode 100644 index 0000000..a86e6f9 Binary files /dev/null and b/debwiki/img/sad.png differ diff --git a/debwiki/img/smile.png b/debwiki/img/smile.png new file mode 100644 index 0000000..361d705 Binary files /dev/null and b/debwiki/img/smile.png differ diff --git a/debwiki/img/smile2.png b/debwiki/img/smile2.png new file mode 100644 index 0000000..cc4bea9 Binary files /dev/null and b/debwiki/img/smile2.png differ diff --git a/debwiki/img/smile3.png b/debwiki/img/smile3.png new file mode 100644 index 0000000..4cf923e Binary files /dev/null and b/debwiki/img/smile3.png differ diff --git a/debwiki/img/smile4.png b/debwiki/img/smile4.png new file mode 100644 index 0000000..96f3af6 Binary files /dev/null and b/debwiki/img/smile4.png differ diff --git a/debwiki/img/star_off.png b/debwiki/img/star_off.png new file mode 100644 index 0000000..2f99cae Binary files /dev/null and b/debwiki/img/star_off.png differ diff --git a/debwiki/img/star_on.png b/debwiki/img/star_on.png new file mode 100644 index 0000000..6a64f93 Binary files /dev/null and b/debwiki/img/star_on.png differ diff --git a/debwiki/img/thumbs-up.png b/debwiki/img/thumbs-up.png new file mode 100644 index 0000000..ca277c6 Binary files /dev/null and b/debwiki/img/thumbs-up.png differ diff --git a/debwiki/img/tired.png b/debwiki/img/tired.png new file mode 100644 index 0000000..077c98d Binary files /dev/null and b/debwiki/img/tired.png differ diff --git a/debwiki/img/tongue.png b/debwiki/img/tongue.png new file mode 100644 index 0000000..7215ac7 Binary files /dev/null and b/debwiki/img/tongue.png differ diff --git a/theme/__init__.py b/theme/__init__.py new file mode 100644 index 0000000..d7e9476 --- /dev/null +++ b/theme/__init__.py @@ -0,0 +1,1816 @@ +# -*- coding: iso-8859-1 -*- +""" + MoinMoin - Theme Package + + @copyright: 2003-2008 MoinMoin:ThomasWaldmann + @license: GNU GPL, see COPYING for details. +""" + +from MoinMoin import i18n, wikiutil, config, version, caching +from MoinMoin.Page import Page +from MoinMoin.util import pysupport + +modules = pysupport.getPackageModules(__file__) + +# Check whether we can emit a RSS feed. +# RSS is broken on plain Python 2.3.x/2.4.x, and works only when installing PyXML. +# News: A user reported that the RSS is valid when using Python 2.5.1 on Windows. +import sys, xml +rss_supported = sys.version_info[:3] >= (2, 5, 1) or '_xmlplus' in xml.__file__ + + +class ThemeBase: + """ Base class for themes + + This class supply all the standard template that sub classes can + use without rewriting the same code. If you want to change certain + elements, override them. + """ + + name = 'base' + + # fake _ function to get gettext recognize those texts: + _ = lambda x: x + + # TODO: remove icons that are not used any more. + icons = { + # key alt icon filename w h + # ------------------------------------------------------------------ + # navibar + 'help': ("%(page_help_contents)s", "moin-help.png", 12, 11), + 'find': ("%(page_find_page)s", "moin-search.png", 12, 12), + 'diff': (_("Diffs"), "moin-diff.png", 15, 11), + 'info': (_("Info"), "moin-info.png", 12, 11), + 'edit': (_("Edit"), "moin-edit.png", 12, 12), + 'unsubscribe': (_("Unsubscribe"), "moin-unsubscribe.png", 14, 10), + 'subscribe': (_("Subscribe"), "moin-subscribe.png", 14, 10), + 'raw': (_("Raw"), "moin-raw.png", 12, 13), + 'xml': (_("XML"), "moin-xml.png", 20, 13), + 'print': (_("Print"), "moin-print.png", 16, 14), + 'view': (_("View"), "moin-show.png", 12, 13), + 'home': (_("Home"), "moin-home.png", 13, 12), + 'up': (_("Up"), "moin-parent.png", 15, 13), + # FileAttach + 'attach': ("%(attach_count)s", "moin-attach.png", 7, 15), + 'attachimg': ("", "attach.png", 32, 32), + # RecentChanges + 'rss': (_("[RSS]"), "moin-rss.png", 24, 24), + 'deleted': (_("[DELETED]"), "moin-deleted.png", 60, 12), + 'updated': (_("[UPDATED]"), "moin-updated.png", 60, 12), + 'renamed': (_("[RENAMED]"), "moin-renamed.png", 60, 12), + 'conflict': (_("[CONFLICT]"), "moin-conflict.png", 60, 12), + 'new': (_("[NEW]"), "moin-new.png", 31, 12), + 'diffrc': (_("[DIFF]"), "moin-diff.png", 15, 11), + # General + 'bottom': (_("[BOTTOM]"), "moin-bottom.png", 14, 10), + 'top': (_("[TOP]"), "moin-top.png", 14, 10), + 'www': ("[WWW]", "moin-www.png", 11, 11), + 'mailto': ("[MAILTO]", "moin-email.png", 14, 10), + 'news': ("[NEWS]", "moin-news.png", 10, 11), + 'telnet': ("[TELNET]", "moin-telnet.png", 10, 11), + 'ftp': ("[FTP]", "moin-ftp.png", 11, 11), + 'file': ("[FILE]", "moin-ftp.png", 11, 11), + # search forms + 'searchbutton': ("[?]", "moin-search.png", 12, 12), + 'interwiki': ("[%(wikitag)s]", "moin-inter.png", 16, 16), + + # smileys (this is CONTENT, but good looking smileys depend on looking + # adapted to the theme background color and theme style in general) + #vvv == vvv this must be the same for GUI editor converter + 'X-(': ("X-(", 'angry.png', 15, 15), + ':D': (":D", 'biggrin.png', 15, 15), + '<:(': ("<:(", 'frown.png', 15, 15), + ':o': (":o", 'redface.png', 15, 15), + ':(': (":(", 'sad.png', 15, 15), + ':)': (":)", 'smile.png', 15, 15), + 'B)': ("B)", 'smile2.png', 15, 15), + ':))': (":))", 'smile3.png', 15, 15), + ';)': (";)", 'smile4.png', 15, 15), + '/!\\': ("/!\\", 'alert.png', 15, 15), + '': ("", 'attention.png', 15, 15), + '(!)': ("(!)", 'idea.png', 15, 15), + + # copied 2001-11-16 from http://pikie.darktech.org/cgi/pikie.py?EmotIcon + ':-?': (":-?", 'tongue.png', 15, 15), + ':\\': (":\\", 'ohwell.png', 15, 15), + '>:>': (">:>", 'devil.png', 15, 15), + '|)': ("|)", 'tired.png', 15, 15), + + # some folks use noses in their emoticons + ':-(': (":-(", 'sad.png', 15, 15), + ':-)': (":-)", 'smile.png', 15, 15), + 'B-)': ("B-)", 'smile2.png', 15, 15), + ':-))': (":-))", 'smile3.png', 15, 15), + ';-)': (";-)", 'smile4.png', 15, 15), + '|-)': ("|-)", 'tired.png', 15, 15), + + # version 1.0 + '(./)': ("(./)", 'checkmark.png', 20, 15), + '{OK}': ("{OK}", 'thumbs-up.png', 14, 12), + '{X}': ("{X}", 'icon-error.png', 16, 16), + '{i}': ("{i}", 'icon-info.png', 16, 16), + '{1}': ("{1}", 'prio1.png', 15, 13), + '{2}': ("{2}", 'prio2.png', 15, 13), + '{3}': ("{3}", 'prio3.png', 15, 13), + + # version 1.3.4 (stars) + # try {*}{*}{o} + '{*}': ("{*}", 'star_on.png', 15, 15), + '{o}': ("{o}", 'star_off.png', 15, 15), + } + del _ + + # Style sheets - usually there is no need to override this in sub + # classes. Simply supply the css files in the css directory. + + # Standard set of style sheets + stylesheets = ( + # media basename + ('all', 'common'), + ('screen', 'screen'), + ('print', 'print'), + ('projection', 'projection'), + ) + + # Used in print mode + stylesheets_print = ( + # media basename + ('all', 'common'), + ('all', 'print'), + ) + + # Used in slide show mode + stylesheets_projection = ( + # media basename + ('all', 'common'), + ('all', 'projection'), + ) + + stylesheetsCharset = 'utf-8' + + def __init__(self, request): + """ + Initialize the theme object. + + @param request: the request object + """ + self.request = request + self.cfg = request.cfg + self._cache = {} # Used to cache elements that may be used several times + self._status = [] + self._send_title_called = False + + def img_url(self, img): + """ Generate an image href + + @param img: the image filename + @rtype: string + @return: the image href + """ + return "%s/%s/img/%s" % (self.cfg.url_prefix_static, self.name, img) + + def emit_custom_html(self, html): + """ + generate custom HTML code in `html` + + @param html: a string or a callable object, in which case + it is called and its return value is used + @rtype: string + @return: string with html + """ + if html: + if callable(html): + html = html(self.request) + return html + + def logo(self): + """ Assemble logo with link to front page + + The logo contain an image and or text or any html markup the + admin inserted in the config file. Everything it enclosed inside + a div with id="logo". + + @rtype: unicode + @return: logo html + """ + html = u'' + if self.cfg.logo_string: + page = wikiutil.getFrontPage(self.request) + logo = page.link_to_raw(self.request, self.cfg.logo_string) + html = u'''''' % logo + return html + + def interwiki(self, d): + """ Assemble the interwiki name display, linking to page_front_page + + @param d: parameter dictionary + @rtype: string + @return: interwiki html + """ + if self.request.cfg.show_interwiki: + page = wikiutil.getFrontPage(self.request) + text = self.request.cfg.interwikiname or 'Self' + link = page.link_to(self.request, text=text, rel='nofollow') + html = u'
%s
' % link + else: + html = u'' + return html + + def title(self, d): + """ Assemble the title (now using breadcrumbs) + + @param d: parameter dictionary + @rtype: string + @return: title html + """ + _ = self.request.getText + content = [] + if d['title_text'] == d['page'].split_title(): # just showing a page, no action + curpage = '' + segments = d['page_name'].split('/') # was: title_text + for s in segments[:-1]: + curpage += s + content.append("
  • %s
  • " % Page(self.request, curpage).link_to(self.request, s)) + curpage += '/' + link_text = segments[-1] + link_title = _('Click to do a full-text search for this title') + link_query = { + 'action': 'fullsearch', + 'value': 'linkto:"%s"' % d['page_name'], + 'context': '180', + } + # we dont use d['title_link'] any more, but make it ourselves: + link = d['page'].link_to(self.request, link_text, querystr=link_query, title=link_title, css_class='backlink', rel='nofollow') + content.append(('
  • %s
  • ') % link) + else: + content.append('
  • %s
  • ' % wikiutil.escape(d['title_text'])) + + html = ''' +
      +%s +
    +''' % "".join(content) + return html + + def username(self, d): + """ Assemble the username / userprefs link + + @param d: parameter dictionary + @rtype: unicode + @return: username html + """ + request = self.request + _ = request.getText + + userlinks = [] + # Add username/homepage link for registered users. We don't care + # if it exists, the user can create it. + if request.user.valid and request.user.name: + interwiki = wikiutil.getInterwikiHomePage(request) + name = request.user.name + aliasname = request.user.aliasname + if not aliasname: + aliasname = name + title = "%s @ %s" % (aliasname, interwiki[0]) + # link to (interwiki) user homepage + homelink = (request.formatter.interwikilink(1, title=title, id="userhome", generated=True, *interwiki) + + request.formatter.text(name) + + request.formatter.interwikilink(0, title=title, id="userhome", *interwiki)) + userlinks.append(homelink) + # link to userprefs action + if 'userprefs' not in self.request.cfg.actions_excluded: + userlinks.append(d['page'].link_to(request, text=_('Settings'), + querystr={'action': 'userprefs'}, id='userprefs', rel='nofollow')) + + if request.user.valid: + if request.user.auth_method in request.cfg.auth_can_logout: + userlinks.append(d['page'].link_to(request, text=_('Logout'), + querystr={'action': 'logout', 'logout': 'logout'}, id='logout', rel='nofollow')) + else: + query = {'action': 'login'} + # special direct-login link if the auth methods want no input + if request.cfg.auth_login_inputs == ['special_no_input']: + query['login'] = '1' + if request.cfg.auth_have_login: + userlinks.append(d['page'].link_to(request, text=_("Login"), + querystr=query, id='login', rel='nofollow')) + + userlinks = [u'
  • %s
  • ' % link for link in userlinks] + html = u'
      %s
    ' % ''.join(userlinks) + return html + + def splitNavilink(self, text, localize=1): + """ Split navibar links into pagename, link to page + + Admin or user might want to use shorter navibar items by using + the [[page|title]] or [[url|title]] syntax. In this case, we don't + use localization, and the links goes to page or to the url, not + the localized version of page. + + Supported syntax: + * PageName + * WikiName:PageName + * wiki:WikiName:PageName + * url + * all targets as seen above with title: [[target|title]] + + @param text: the text used in config or user preferences + @rtype: tuple + @return: pagename or url, link to page or url + """ + request = self.request + fmt = request.formatter + title = None + + # Handle [[pagename|title]] or [[url|title]] formats + if text.startswith('[[') and text.endswith(']]'): + text = text[2:-2] + try: + pagename, title = text.split('|', 1) + pagename = pagename.strip() + title = title.strip() + localize = 0 + except (ValueError, TypeError): + # Just use the text as is. + pagename = text.strip() + else: + pagename = text + + if wikiutil.is_URL(pagename): + if not title: + title = pagename + link = fmt.url(1, pagename) + fmt.text(title) + fmt.url(0) + return pagename, link + + # remove wiki: url prefix + if pagename.startswith("wiki:"): + pagename = pagename[5:] + + # try handling interwiki links + try: + interwiki, page = wikiutil.split_interwiki(pagename) + thiswiki = request.cfg.interwikiname + if interwiki == thiswiki or interwiki == 'Self': + pagename = page + else: + if not title: + title = page + link = fmt.interwikilink(True, interwiki, page) + fmt.text(title) + fmt.interwikilink(False, interwiki, page) + return pagename, link + except ValueError: + pass + + # Handle regular pagename like "FrontPage" + pagename = request.normalizePagename(pagename) + + # Use localized pages for the current user + if localize: + page = wikiutil.getLocalizedPage(request, pagename) + else: + page = Page(request, pagename) + + pagename = page.page_name # can be different, due to i18n + + if not title: + title = page.split_title() + title = self.shortenPagename(title) + + link = page.link_to(request, title) + + return pagename, link + + def shortenPagename(self, name): + """ Shorten page names + + Shorten very long page names that tend to break the user + interface. The short name is usually fine, unless really stupid + long names are used (WYGIWYD). + + If you don't like to do this in your theme, or want to use + different algorithm, override this method. + + @param name: page name, unicode + @rtype: unicode + @return: shortened version. + """ + maxLength = self.maxPagenameLength() + # First use only the sub page name, that might be enough + if len(name) > maxLength: + name = name.split('/')[-1] + # If it's not enough, replace the middle with '...' + if len(name) > maxLength: + half, left = divmod(maxLength - 3, 2) + name = u'%s...%s' % (name[:half + left], name[-half:]) + return name + + def maxPagenameLength(self): + """ Return maximum length for shortened page names """ + return 25 + + def navibar(self, d): + """ Assemble the navibar + + @param d: parameter dictionary + @rtype: unicode + @return: navibar html + """ + request = self.request + found = {} # pages we found. prevent duplicates + items = [] # navibar items + item = u'
  • %s
  • ' + current = d['page_name'] + + # Process config navi_bar + if request.cfg.navi_bar: + for text in request.cfg.navi_bar: + pagename, link = self.splitNavilink(text) + if pagename == current: + cls = 'wikilink current' + else: + cls = 'wikilink' + items.append(item % (cls, link)) + found[pagename] = 1 + + # Add user links to wiki links, eliminating duplicates. + userlinks = request.user.getQuickLinks() + for text in userlinks: + # Split text without localization, user knows what he wants + pagename, link = self.splitNavilink(text, localize=0) + if not pagename in found: + if pagename == current: + cls = 'userlink current' + else: + cls = 'userlink' + items.append(item % (cls, link)) + found[pagename] = 1 + + # Add current page at end of local pages + if not current in found: + title = d['page'].split_title() + title = self.shortenPagename(title) + link = d['page'].link_to(request, title) + cls = 'current' + items.append(item % (cls, link)) + + # Add sister pages. + for sistername, sisterurl in request.cfg.sistersites: + if sistername == request.cfg.interwikiname: # it is THIS wiki + cls = 'sisterwiki current' + items.append(item % (cls, sistername)) + else: + # TODO optimize performance + cache = caching.CacheEntry(request, 'sisters', sistername, 'farm', use_pickle=True) + if cache.exists(): + data = cache.content() + sisterpages = data['sisterpages'] + if current in sisterpages: + cls = 'sisterwiki' + url = sisterpages[current] + link = request.formatter.url(1, url) + \ + request.formatter.text(sistername) +\ + request.formatter.url(0) + items.append(item % (cls, link)) + + # Assemble html + items = u''.join(items) + html = u''' + +''' % items + return html + + def get_icon(self, icon): + """ Return icon data from self.icons + + If called from <> we have a filename, not a + key. Using filenames is deprecated, but for now, we simulate old + behavior. + + @param icon: icon name or file name (string) + @rtype: tuple + @return: alt (unicode), href (string), width, height (int) + """ + if icon in self.icons: + alt, icon, w, h = self.icons[icon] + else: + # Create filenames to icon data mapping on first call, then + # cache in class for next calls. + if not getattr(self.__class__, 'iconsByFile', None): + d = {} + for data in self.icons.values(): + d[data[1]] = data + self.__class__.iconsByFile = d + + # Try to get icon data by file name + if icon in self.iconsByFile: + alt, icon, w, h = self.iconsByFile[icon] + else: + alt, icon, w, h = '', icon, '', '' + + return alt, self.img_url(icon), w, h + + def make_icon(self, icon, vars=None, **kw): + """ + This is the central routine for making tags for icons! + All icons stuff except the top left logo and search field icons are + handled here. + + @param icon: icon id (dict key) + @param vars: ... + @rtype: string + @return: icon html (img tag) + """ + if vars is None: + vars = {} + alt, img, w, h = self.get_icon(icon) + try: + alt = vars['icon-alt-text'] # if it is possible we take the alt-text from 'page_icons_table' + except KeyError, err: + try: + alt = alt % vars # if not we just leave the alt-text from 'icons' + except KeyError, err: + alt = 'KeyError: %s' % str(err) + alt = self.request.getText(alt) + tag = self.request.formatter.image(src=img, alt=alt, width=w, height=h, **kw) + return tag + + def make_iconlink(self, which, d): + """ + Make a link with an icon + + @param which: icon id (dictionary key) + @param d: parameter dictionary + @rtype: string + @return: html link tag + """ + qs = {} + pagekey, querystr, title, icon = self.cfg.page_icons_table[which] + qs.update(querystr) # do not modify the querystr dict in the cfg! + d['icon-alt-text'] = d['title'] = title % d + d['i18ntitle'] = self.request.getText(d['title']) + img_src = self.make_icon(icon, d) + rev = d['rev'] + if rev and which in ['raw', 'print', ]: + qs['rev'] = str(rev) + attrs = {'rel': 'nofollow', 'title': d['i18ntitle'], } + page = d[pagekey] + if isinstance(page, unicode): + # e.g. d['page_parent_page'] is just the unicode pagename + # while d['page'] will give a page object + page = Page(self.request, page) + return page.link_to_raw(self.request, text=img_src, querystr=qs, **attrs) + + def msg(self, d): + """ Assemble the msg display + + Display a message with a widget or simple strings with a clear message link. + + @param d: parameter dictionary + @rtype: unicode + @return: msg display html + """ + _ = self.request.getText + msgs = d['msg'] + + result = u"" + close = d['page'].link_to(self.request, text=_('Clear message'), css_class="clear-link") + for msg, msg_class in msgs: + try: + result += u'

    %s

    ' % msg.render() + close = '' + except AttributeError: + if msg and msg_class: + result += u'

    %s

    ' % (msg_class, msg) + elif msg: + result += u'

    %s

    \n' % msg + if result: + html = result + close + return u'
    \n%s\n
    \n' % html + else: + return u'' + + return u'
    \n%s\n
    \n' % html + + def trail(self, d): + """ Assemble page trail + + @param d: parameter dictionary + @rtype: unicode + @return: trail html + """ + request = self.request + user = request.user + html = '' + if not user.valid or user.show_page_trail: + trail = user.getTrail() + if trail: + items = [] + for pagename in trail: + try: + interwiki, page = wikiutil.split_interwiki(pagename) + if interwiki != request.cfg.interwikiname and interwiki != 'Self': + link = (self.request.formatter.interwikilink(True, interwiki, page) + + self.shortenPagename(page) + + self.request.formatter.interwikilink(False, interwiki, page)) + items.append('
  • %s
  • ' % link) + continue + else: + pagename = page + + except ValueError: + pass + page = Page(request, pagename) + title = page.split_title() + title = self.shortenPagename(title) + link = page.link_to(request, title) + items.append('
  • %s
  • ' % link) + html = ''' +
      +%s +
    ''' % ''.join(items) + return html + + def html_stylesheets(self, d): + """ Assemble html head stylesheet links + + @param d: parameter dictionary + @rtype: string + @return: stylesheets links + """ + link = '' + + # Check mode + if d.get('print_mode'): + media = d.get('media', 'print') + stylesheets = getattr(self, 'stylesheets_' + media) + else: + stylesheets = self.stylesheets + usercss = self.request.user.valid and self.request.user.css_url + + # Create stylesheets links + html = [] + prefix = self.cfg.url_prefix_static + csshref = '%s/%s/css' % (prefix, self.name) + for media, basename in stylesheets: + href = '%s/%s.css' % (csshref, basename) + html.append(link % (self.stylesheetsCharset, media, href)) + + # Don't add user css url if it matches one of ours + if usercss and usercss == href: + usercss = None + + # admin configurable additional css (farm or wiki level) + for media, csshref in self.request.cfg.stylesheets: + html.append(link % (self.stylesheetsCharset, media, csshref)) + + csshref = '%s/%s/css/msie.css' % (prefix, self.name) + html.append(""" + + +""" % link % (self.stylesheetsCharset, 'all', csshref)) + + # Add user css url (assuming that user css uses same charset) + if usercss and usercss.lower() != "none": + html.append(link % (self.stylesheetsCharset, 'all', usercss)) + + return '\n'.join(html) + + def shouldShowPageinfo(self, page): + """ Should we show page info? + + Should be implemented by actions. For now, we check here by action + name and page. + + @param page: current page + @rtype: bool + @return: true if should show page info + """ + if page.exists() and self.request.user.may.read(page.page_name): + # These actions show the page content. + # TODO: on new action, page info will not show. + # A better solution will be if the action itself answer the question: showPageInfo(). + contentActions = [u'', u'show', u'refresh', u'preview', u'diff', + u'subscribe', u'RenamePage', u'CopyPage', u'DeletePage', + u'SpellCheck', u'print'] + return self.request.action in contentActions + return False + + def pageinfo(self, page): + """ Return html fragment with page meta data + + Since page information uses translated text, it uses the ui + language and direction. It looks strange sometimes, but + translated text using page direction looks worse. + + @param page: current page + @rtype: unicode + @return: page last edit information + """ + _ = self.request.getText + html = '' + if self.shouldShowPageinfo(page): + info = page.lastEditInfo() + if info: + if info['editor']: + info = _("last edited %(time)s by %(editor)s") % info + else: + info = _("last modified %(time)s") % info + pagename = page.page_name + if self.request.cfg.show_interwiki: + pagename = "%s: %s" % (self.request.cfg.interwikiname, pagename) + info = "%s (%s)" % (wikiutil.escape(pagename), info) + html = '

    %(info)s

    \n' % { + 'lang': self.ui_lang_attr(), + 'info': info + } + return html + + def searchform(self, d): + """ + assemble HTML code for the search forms + + @param d: parameter dictionary + @rtype: unicode + @return: search form html + """ + _ = self.request.getText + form = self.request.form + updates = { + 'search_label': _('Search:'), + 'search_value': wikiutil.escape(form.get('value', [''])[0], 1), + 'search_full_label': _('Text'), + 'search_title_label': _('Titles'), + 'baseurl': self.request.getScriptname(), + 'pagename_quoted': wikiutil.quoteWikinameURL(d['page'].page_name), + } + d.update(updates) + + html = u''' +
    +
    + + + + + + +
    +
    + +''' % d + return html + + def showversion(self, d, **keywords): + """ + assemble HTML code for copyright and version display + + @param d: parameter dictionary + @rtype: string + @return: copyright and version display html + """ + html = '' + if self.cfg.show_version and not keywords.get('print_mode', 0): + html = (u'
    MoinMoin Release %s [Revision %s], ' + 'Copyright by Juergen Hermann et al.
    ') % (version.release, version.revision, ) + return html + + def headscript(self, d): + """ Return html head script with common functions + + @param d: parameter dictionary + @rtype: unicode + @return: script for html head + """ + # Don't add script for print view + if self.request.action == 'print': + return u'' + + _ = self.request.getText + script = u""" + +""" % { + 'search_hint': _('Search Wiki'), + } + return script + + def shouldUseRSS(self, page): + """ Return True if RSS feature is available and we are on the + RecentChanges page, or False. + + Currently rss is broken on plain Python, and works only when + installing PyXML. Return true if PyXML is installed. + """ + if not rss_supported: + return False + return page.page_name == u'RecentChanges' or \ + page.page_name == self.request.getText(u'RecentChanges') + + def rsshref(self, page): + """ Create rss href, used for rss button and head link + + @rtype: unicode + @return: rss href + """ + request = self.request + url = page.url(request, querystr={ + 'action': 'rss_rc', 'ddiffs': '1', 'unique': '1', }, escape=0) + return url + + def rsslink(self, d): + """ Create rss link in head, used by FireFox + + RSS link for FireFox. This shows an rss link in the bottom of + the page and let you subscribe to the wiki rss feed. + + @rtype: unicode + @return: html head + """ + link = u'' + page = d['page'] + if self.shouldUseRSS(page): + link = (u'') % ( + wikiutil.escape(self.cfg.sitename, True), + wikiutil.escape(self.rsshref(page), True) ) + return link + + def html_head(self, d): + """ Assemble html head + + @param d: parameter dictionary + @rtype: unicode + @return: html head + """ + html = [ + u'%(title)s - %(sitename)s' % { + 'title': wikiutil.escape(d['title']), + 'sitename': wikiutil.escape(d['sitename']), + }, + self.externalScript('common'), + self.headscript(d), # Should move to separate .js file + self.guiEditorScript(d), + self.html_stylesheets(d), + self.rsslink(d), + self.universal_edit_button(d), + ] + return '\n'.join(html) + + def externalScript(self, name): + """ Format external script html """ + src = '%s/common/js/%s.js' % (self.request.cfg.url_prefix_static, name) + return '' % src + + def universal_edit_button(self, d, **keywords): + """ Generate HTML for an edit link in the header.""" + page = d['page'] + if 'edit' in self.request.cfg.actions_excluded: + return "" + if not (page.isWritable() and + self.request.user.may.write(page.page_name)): + return "" + _ = self.request.getText + querystr = {'action': 'edit'} + text = _(u'Edit') + url = page.url(self.request, querystr=querystr, escape=0) + return (u'' % (text, url)) + + def credits(self, d, **keywords): + """ Create credits html from credits list """ + if isinstance(self.cfg.page_credits, (list, tuple)): + items = ['
  • %s
  • ' % i for i in self.cfg.page_credits] + html = '
      \n%s\n
    \n' % ''.join(items) + else: + # Old config using string, output as is + html = self.cfg.page_credits + return html + + def actionsMenu(self, page): + """ Create actions menu list and items data dict + + The menu will contain the same items always, but items that are + not available will be disabled (some broken browsers will let + you select disabled options though). + + The menu should give best user experience for javascript + enabled browsers, and acceptable behavior for those who prefer + not to use Javascript. + + TODO: Move actionsMenuInit() into body onload - requires that the theme will render body, + it is currently done in wikiutil/page. + + @param page: current page, Page object + @rtype: unicode + @return: actions menu html fragment + """ + request = self.request + _ = request.getText + rev = request.rev + + menu = [ + 'raw', + 'print', + 'RenderAsDocbook', + 'refresh', + '__separator__', + 'SpellCheck', + 'LikePages', + 'LocalSiteMap', + '__separator__', + 'RenamePage', + 'CopyPage', + 'DeletePage', + '__separator__', + 'MyPages', + 'SubscribeUser', + '__separator__', + 'Despam', + 'revert', + 'PackagePages', + 'SyncPages', + ] + + titles = { + # action: menu title + '__title__': _("More Actions:"), + # Translation may need longer or shorter separator + '__separator__': _('------------------------'), + 'raw': _('Raw Text'), + 'print': _('Print View'), + 'refresh': _('Delete Cache'), + 'SpellCheck': _('Check Spelling'), # rename action! + 'RenamePage': _('Rename Page'), + 'CopyPage': _('Copy Page'), + 'DeletePage': _('Delete Page'), + 'LikePages': _('Like Pages'), + 'LocalSiteMap': _('Local Site Map'), + 'MyPages': _('My Pages'), + 'SubscribeUser': _('Subscribe User'), + 'Despam': _('Remove Spam'), + 'revert': _('Revert to this revision'), + 'PackagePages': _('Package Pages'), + 'RenderAsDocbook': _('Render as Docbook'), + 'SyncPages': _('Sync Pages'), + } + + options = [] + option = '' + # class="disabled" is a workaround for browsers that ignore + # "disabled", e.g IE, Safari + # for XHTML: data['disabled'] = ' disabled="disabled"' + disabled = ' disabled class="disabled"' + + # Format standard actions + available = request.getAvailableActions(page) + for action in menu: + data = {'action': action, 'disabled': '', 'title': titles[action]} + # removes excluded actions from the more actions menu + if action in request.cfg.actions_excluded: + continue + + # Enable delete cache only if page can use caching + if action == 'refresh': + if not page.canUseCache(): + data['action'] = 'show' + data['disabled'] = disabled + + # revert action enabled only if user can revert + if action == 'revert' and not request.user.may.revert(page.page_name): + data['action'] = 'show' + data['disabled'] = disabled + + # SubscribeUser action enabled only if user has admin rights + if action == 'SubscribeUser' and not request.user.may.admin(page.page_name): + data['action'] = 'show' + data['disabled'] = disabled + + # PackagePages action only if user has write rights + if action == 'PackagePages' and not request.user.may.write(page.page_name): + data['action'] = 'show' + data['disabled'] = disabled + + # Despam action enabled only for superusers + if action == 'Despam' and not request.user.isSuperUser(): + data['action'] = 'show' + data['disabled'] = disabled + + # Special menu items. Without javascript, executing will + # just return to the page. + if action.startswith('__'): + data['action'] = 'show' + + # Actions which are not available for this wiki, user or page + if (action == '__separator__' or + (action[0].isupper() and not action in available)): + data['disabled'] = disabled + + options.append(option % data) + + # Add custom actions not in the standard menu, except for + # some actions like AttachFile (we have them on top level) + more = [item for item in available if not item in titles and not item in ('AttachFile', )] + more.sort() + if more: + # Add separator + separator = option % {'action': 'show', 'disabled': disabled, + 'title': titles['__separator__']} + options.append(separator) + # Add more actions (all enabled) + for action in more: + data = {'action': action, 'disabled': ''} + # Always add spaces: AttachFile -> Attach File + # XXX do not create page just for using split_title - + # creating pages for non-existent does 2 storage lookups + #title = Page(request, action).split_title(force=1) + title = action + # Use translated version if available + data['title'] = _(title) + options.append(option % data) + + data = { + 'label': titles['__title__'], + 'options': '\n'.join(options), + 'rev_field': rev and '' % rev or '', + 'do_button': _("Do"), + 'baseurl': self.request.getScriptname(), + 'pagename_quoted': wikiutil.quoteWikinameURL(page.page_name), + } + html = ''' +
    +
    + + + + %(rev_field)s +
    + +
    +''' % data + + return html + + def editbar(self, d): + """ Assemble the page edit bar. + + Create html on first call, then return cached html. + + @param d: parameter dictionary + @rtype: unicode + @return: iconbar html + """ + page = d['page'] + if not self.shouldShowEditbar(page): + return '' + + html = self._cache.get('editbar') + if html is None: + # Remove empty items and format as list + items = ''.join(['
  • %s
  • ' % item + for item in self.editbarItems(page) if item]) + html = u'
      %s
    \n' % items + self._cache['editbar'] = html + + return html + + def shouldShowEditbar(self, page): + """ Should we show the editbar? + + Actions should implement this, because only the action knows if + the edit bar makes sense. Until it goes into actions, we do the + checking here. + + @param page: current page + @rtype: bool + @return: true if editbar should show + """ + # Show editbar only for existing pages, including deleted pages, + # that the user may read. If you may not read, you can't edit, + # so you don't need editbar. + if (page.exists(includeDeleted=1) and + self.request.user.may.read(page.page_name)): + form = self.request.form + action = self.request.action + # Do not show editbar on edit but on save/cancel + return not (action == 'edit' and + not form.has_key('button_save') and + not form.has_key('button_cancel')) + return False + + def editbarItems(self, page): + """ Return list of items to show on the editbar + + This is separate method to make it easy to customize the + edtibar in sub classes. + """ + _ = self.request.getText + editbar_actions = [] + for editbar_item in self.request.cfg.edit_bar: + if editbar_item == 'Discussion': + if not self.request.cfg.supplementation_page and self.request.getPragma('supplementation-page', 1) in ('on', '1'): + editbar_actions.append(self.supplementation_page_nameLink(page)) + elif self.request.cfg.supplementation_page and not self.request.getPragma('supplementation-page', 1) in ('off', '0'): + editbar_actions.append(self.supplementation_page_nameLink(page)) + elif editbar_item == 'Comments': + # we just use to get same style as other links, but we add some dummy + # link target to get correct mouseover pointer appearance. return false + # keeps the browser away from jumping to the link target:: + editbar_actions.append('' % _('Comments')) + elif editbar_item == 'Edit': + editbar_actions.append(self.editorLink(page)) + elif editbar_item == 'Info': + editbar_actions.append(self.infoLink(page)) + elif editbar_item == 'Subscribe': + editbar_actions.append(self.subscribeLink(page)) + elif editbar_item == 'Quicklink': + editbar_actions.append(self.quicklinkLink(page)) + elif editbar_item == 'Attachments': + editbar_actions.append(self.attachmentsLink(page)) + elif editbar_item == 'ActionsMenu': + editbar_actions.append(self.actionsMenu(page)) + return editbar_actions + + def supplementation_page_nameLink(self, page): + """Return a link to the discussion page + + If the discussion page doesn't exist and the user + has no right to create it, show a disabled link. + """ + _ = self.request.getText + suppl_name = self.request.cfg.supplementation_page_name + suppl_name_full = "%s/%s" % (page.page_name, suppl_name) + + test = Page(self.request, suppl_name_full) + if not test.exists() and not self.request.user.may.write(suppl_name_full): + return ('%s' % _(suppl_name)) + else: + return page.link_to(self.request, text=_(suppl_name), + querystr={'action': 'supplementation'}, css_class='nbsupplementation', rel='nofollow') + + def guiworks(self, page): + """ Return whether the gui editor / converter can work for that page. + + The GUI editor currently only works for wiki format. + For simplicity, we also tell it does not work if the admin forces the text editor. + """ + is_wiki = page.pi['format'] == 'wiki' + gui_disallowed = self.cfg.editor_force and self.cfg.editor_default == 'text' + return is_wiki and not gui_disallowed + + + def editorLink(self, page): + """ Return a link to the editor + + If the user can't edit, return a disabled edit link. + + If the user want to show both editors, it will display "Edit + (Text)", otherwise as "Edit". + """ + if 'edit' in self.request.cfg.actions_excluded: + return "" + + if not (page.isWritable() and + self.request.user.may.write(page.page_name)): + return self.disabledEdit() + + _ = self.request.getText + querystr = {'action': 'edit'} + + guiworks = self.guiworks(page) + if self.showBothEditLinks() and guiworks: + text = _('Edit (Text)') + querystr['editor'] = 'text' + attrs = {'name': 'texteditlink', 'rel': 'nofollow', } + else: + text = _('Edit') + if guiworks: + # 'textonly' will be upgraded dynamically to 'guipossible' by JS + querystr['editor'] = 'textonly' + attrs = {'name': 'editlink', 'rel': 'nofollow', } + else: + querystr['editor'] = 'text' + attrs = {'name': 'texteditlink', 'rel': 'nofollow', } + + return page.link_to(self.request, text=text, querystr=querystr, **attrs) + + def showBothEditLinks(self): + """ Return True if both edit links should be displayed """ + editor = self.request.user.editor_ui + if editor == '': + editor = self.request.cfg.editor_ui + return editor == 'freechoice' + + def guiEditorScript(self, d): + """ Return a script that set the gui editor link variables + + The link will be created only when javascript is enabled and + the browser is compatible with the editor. + """ + page = d['page'] + if not (page.isWritable() and + self.request.user.may.write(page.page_name) and + self.showBothEditLinks() and + self.guiworks(page)): + return '' + + _ = self.request.getText + return """\ + +""" % {'url': page.url(self.request, querystr={'action': 'edit', 'editor': 'gui', }), + 'text': _('Edit (GUI)'), + } + + def disabledEdit(self): + """ Return a disabled edit link """ + _ = self.request.getText + return ('%s' + % _('Immutable Page')) + + def infoLink(self, page): + """ Return link to page information """ + if 'info' in self.request.cfg.actions_excluded: + return "" + + _ = self.request.getText + return page.link_to(self.request, + text=_('Info'), + querystr={'action': 'info'}, css_class='nbinfo', rel='nofollow') + + def subscribeLink(self, page): + """ Return subscribe/unsubscribe link to valid users + + @rtype: unicode + @return: subscribe or unsubscribe link + """ + if not ((self.cfg.mail_enabled or self.cfg.jabber_enabled) and self.request.user.valid): + return '' + + _ = self.request.getText + if self.request.user.isSubscribedTo([page.page_name]): + action, text = 'unsubscribe', _("Unsubscribe") + else: + action, text = 'subscribe', _("Subscribe") + if action in self.request.cfg.actions_excluded: + return "" + return page.link_to(self.request, text=text, querystr={'action': action}, css_class='nbsubscribe', rel='nofollow') + + def quicklinkLink(self, page): + """ Return add/remove quicklink link + + @rtype: unicode + @return: link to add or remove a quicklink + """ + if not self.request.user.valid: + return '' + + _ = self.request.getText + if self.request.user.isQuickLinkedTo([page.page_name]): + action, text = 'quickunlink', _("Remove Link") + else: + action, text = 'quicklink', _("Add Link") + if action in self.request.cfg.actions_excluded: + return "" + return page.link_to(self.request, text=text, querystr={'action': action}, css_class='nbquicklink', rel='nofollow') + + def attachmentsLink(self, page): + """ Return link to page attachments """ + if 'AttachFile' in self.request.cfg.actions_excluded: + return "" + + _ = self.request.getText + return page.link_to(self.request, + text=_('Attachments'), + querystr={'action': 'AttachFile'}, css_class='nbattachments', rel='nofollow') + + def startPage(self): + """ Start page div with page language and direction + + @rtype: unicode + @return: page div with language and direction attribtues + """ + return u'
    \n' % self.content_lang_attr() + + def endPage(self): + """ End page div + + Add an empty page bottom div to prevent floating elements to + float out of the page bottom over the footer. + """ + return '
    \n
    \n' + + # Public functions ##################################################### + + def header(self, d, **kw): + """ Assemble page header + + Default behavior is to start a page div. Sub class and add + footer items. + + @param d: parameter dictionary + @rtype: string + @return: page header html + """ + return self.startPage() + + editorheader = header + + def footer(self, d, **keywords): + """ Assemble page footer + + Default behavior is to end page div. Sub class and add + footer items. + + @param d: parameter dictionary + @keyword ...:... + @rtype: string + @return: page footer html + """ + return self.endPage() + + # RecentChanges ###################################################### + + def recentchanges_entry(self, d): + """ + Assemble a single recentchanges entry (table row) + + @param d: parameter dictionary + @rtype: string + @return: recentchanges entry html + """ + _ = self.request.getText + html = [] + html.append('\n') + + html.append('%(icon_html)s\n' % d) + + html.append('%(pagelink_html)s\n' % d) + + html.append('') + if d['time_html']: + html.append("%(time_html)s" % d) + html.append('\n') + + html.append('%(info_html)s\n' % d) + + html.append('') + if d['editors']: + html.append('
    '.join(d['editors'])) + html.append('\n') + + html.append('') + if d['comments']: + if d['changecount'] > 1: + notfirst = 0 + for comment in d['comments']: + html.append('%s#%02d %s' % ( + notfirst and '
    ' or '', comment[0], comment[1])) + notfirst = 1 + else: + comment = d['comments'][0] + html.append('%s' % comment[1]) + html.append('\n') + + html.append('\n') + + return ''.join(html) + + def recentchanges_daybreak(self, d): + """ + Assemble a rc daybreak indication (table row) + + @param d: parameter dictionary + @rtype: string + @return: recentchanges daybreak html + """ + if d['bookmark_link_html']: + set_bm = '  %(bookmark_link_html)s' % d + else: + set_bm = '' + return ('' + '%s' + '%s' + '\n') % (6, d['date'], set_bm) + + def recentchanges_header(self, d): + """ + Assemble the recentchanges header (intro + open table) + + @param d: parameter dictionary + @rtype: string + @return: recentchanges header html + """ + _ = self.request.getText + + # Should use user interface language and direction + html = '
    \n' % self.ui_lang_attr() + html += '
    \n' + page = d['page'] + if self.shouldUseRSS(page): + link = [ + u'
    ', + self.request.formatter.url(1, self.rsshref(page)), + self.request.formatter.rawHTML(self.make_icon("rss")), + self.request.formatter.url(0), + u'
    ', + ] + html += ''.join(link) + html += '

    ' + # Add day selector + if d['rc_days']: + days = [] + for day in d['rc_days']: + if day == d['rc_max_days']: + days.append('%d' % day) + else: + days.append( + wikiutil.link_tag(self.request, + '%s?max_days=%d' % (d['q_page_name'], day), + str(day), + self.request.formatter, rel='nofollow')) + days = ' | '.join(days) + html += (_("Show %s days.") % (days, )) + + if d['rc_update_bookmark']: + html += " %(rc_update_bookmark)s %(rc_curr_bookmark)s" % d + + html += '

    \n
    \n' + + html += '\n' + return html + + def recentchanges_footer(self, d): + """ + Assemble the recentchanges footer (close table) + + @param d: parameter dictionary + @rtype: string + @return: recentchanges footer html + """ + _ = self.request.getText + html = '' + html += '
    \n' + if d['rc_msg']: + html += "
    %(rc_msg)s\n" % d + html += '
    \n' + return html + + # Language stuff #################################################### + + def ui_lang_attr(self): + """Generate language attributes for user interface elements + + User interface elements use the user language (if any), kept in + request.lang. + + @rtype: string + @return: lang and dir html attributes + """ + lang = self.request.lang + return ' lang="%s" dir="%s"' % (lang, i18n.getDirection(lang)) + + def content_lang_attr(self): + """Generate language attributes for wiki page content + + Page content uses the page language or the wiki default language. + + @rtype: string + @return: lang and dir html attributes + """ + lang = self.request.content_lang + return ' lang="%s" dir="%s"' % (lang, i18n.getDirection(lang)) + + def add_msg(self, msg, msg_class=None): + """ Adds a message to a list which will be used to generate status + information. + + @param msg: additional message + @param msg_class: html class for the div of the additional message. + """ + if not msg_class: + msg_class = 'dialog' + if self._send_title_called: + raise Exception("You cannot call add_msg() after send_title()") + self._status.append((msg, msg_class)) + + # stuff from wikiutil.py + def send_title(self, text, **keywords): + """ + Output the page header (and title). + + @param text: the title text + @keyword page: the page instance that called us - using this is more efficient than using pagename.. + @keyword pagename: 'PageName' + @keyword print_mode: 1 (or 0) + @keyword editor_mode: 1 (or 0) + @keyword media: css media type, defaults to 'screen' + @keyword allow_doubleclick: 1 (or 0) + @keyword html_head: additional code + @keyword body_attr: additional attributes + @keyword body_onload: additional "onload" JavaScript code + """ + request = self.request + _ = request.getText + rev = request.rev + + if keywords.has_key('page'): + page = keywords['page'] + pagename = page.page_name + else: + pagename = keywords.get('pagename', '') + page = Page(request, pagename) + if keywords.get('msg', ''): + raise DeprecationWarning("Using send_page(msg=) is deprecated! Use theme.add_msg() instead!") + scriptname = request.getScriptname() + pagename_quoted = wikiutil.quoteWikinameURL(pagename) + + # get name of system pages + page_front_page = wikiutil.getFrontPage(request).page_name + page_help_contents = wikiutil.getLocalizedPage(request, 'HelpContents').page_name + page_title_index = wikiutil.getLocalizedPage(request, 'TitleIndex').page_name + page_site_navigation = wikiutil.getLocalizedPage(request, 'SiteNavigation').page_name + page_word_index = wikiutil.getLocalizedPage(request, 'WordIndex').page_name + page_help_formatting = wikiutil.getLocalizedPage(request, 'HelpOnFormatting').page_name + page_find_page = wikiutil.getLocalizedPage(request, 'FindPage').page_name + home_page = wikiutil.getInterwikiHomePage(request) # sorry theme API change!!! Either None or tuple (wikiname,pagename) now. + page_parent_page = getattr(page.getParentPage(), 'page_name', None) + + # Prepare the HTML element + user_head = [request.cfg.html_head] + + # include charset information - needed for moin_dump or any other case + # when reading the html without a web server + user_head.append('''\n''' % (page.output_mimetype, page.output_charset)) + + meta_keywords = request.getPragma('keywords') + meta_desc = request.getPragma('description') + if meta_keywords: + user_head.append('\n' % wikiutil.escape(meta_keywords, 1)) + if meta_desc: + user_head.append('\n' % wikiutil.escape(meta_desc, 1)) + + # search engine precautions / optimization: + # if it is an action or edit/search, send query headers (noindex,nofollow): + if request.query_string: + user_head.append(request.cfg.html_head_queries) + elif request.request_method == 'POST': + user_head.append(request.cfg.html_head_posts) + # we don't want to have BadContent stuff indexed: + elif pagename in ['BadContent', 'LocalBadContent', ]: + user_head.append(request.cfg.html_head_posts) + # if it is a special page, index it and follow the links - we do it + # for the original, English pages as well as for (the possibly + # modified) frontpage: + elif pagename in [page_front_page, request.cfg.page_front_page, + page_title_index, 'TitleIndex', + page_find_page, 'FindPage', + page_site_navigation, 'SiteNavigation', + 'RecentChanges', ]: + user_head.append(request.cfg.html_head_index) + # if it is a normal page, index it, but do not follow the links, because + # there are a lot of illegal links (like actions) or duplicates: + else: + user_head.append(request.cfg.html_head_normal) + + if 'pi_refresh' in keywords and keywords['pi_refresh']: + user_head.append('' % keywords['pi_refresh']) + + # output buffering increases latency but increases throughput as well + output = [] + # later: + output.append("""\ + + + +%s +%s +%s +""" % ( + ''.join(user_head), + self.html_head({ + 'page': page, + 'title': text, + 'sitename': request.cfg.html_pagetitle or request.cfg.sitename, + 'print_mode': keywords.get('print_mode', False), + 'media': keywords.get('media', 'screen'), + }), + keywords.get('html_head', ''), + )) + + # Links + output.append('\n' % (scriptname, wikiutil.quoteWikinameURL(page_front_page))) + if pagename: + output.append('\n' % ( + _('Wiki Markup'), scriptname, pagename_quoted, )) + output.append('\n' % ( + _('Print View'), scriptname, pagename_quoted, )) + + # !!! currently disabled due to Mozilla link prefetching, see + # http://www.mozilla.org/projects/netlib/Link_Prefetching_FAQ.html + #~ all_pages = request.getPageList() + #~ if all_pages: + #~ try: + #~ pos = all_pages.index(pagename) + #~ except ValueError: + #~ # this shopuld never happend in theory, but let's be sure + #~ pass + #~ else: + #~ request.write('\n' % (request.getScriptname(), quoteWikinameURL(all_pages[0])) + #~ if pos > 0: + #~ request.write('\n' % (request.getScriptname(), quoteWikinameURL(all_pages[pos-1]))) + #~ if pos+1 < len(all_pages): + #~ request.write('\n' % (request.getScriptname(), quoteWikinameURL(all_pages[pos+1]))) + #~ request.write('\n' % (request.getScriptname(), quoteWikinameURL(all_pages[-1]))) + + if page_parent_page: + output.append('\n' % (scriptname, wikiutil.quoteWikinameURL(page_parent_page))) + + # write buffer because we call AttachFile + request.write(''.join(output)) + output = [] + + # XXX maybe this should be removed completely. moin emits all attachments as + # and it is at least questionable if this fits into the original intent of rel="Appendix". + if pagename and request.user.may.read(pagename): + from MoinMoin.action import AttachFile + AttachFile.send_link_rel(request, pagename) + + output.extend([ + '\n' % (scriptname, wikiutil.quoteWikinameURL(page_find_page)), + '\n' % (scriptname, wikiutil.quoteWikinameURL(page_title_index)), + '\n' % (scriptname, wikiutil.quoteWikinameURL(page_word_index)), + '\n' % (scriptname, wikiutil.quoteWikinameURL(page_help_formatting)), + ]) + + output.append("\n") + request.write(''.join(output)) + output = [] + request.flush() + + # start the + bodyattr = [] + if keywords.has_key('body_attr'): + bodyattr.append(' ') + bodyattr.append(keywords['body_attr']) + + # Add doubleclick edit action + if (pagename and keywords.get('allow_doubleclick', 0) and + not keywords.get('print_mode', 0) and + request.user.edit_on_doubleclick): + if request.user.may.write(pagename): # separating this gains speed + url = page.url(request, {'action': 'edit'}) + bodyattr.append(''' ondblclick="location.href='%s'" ''' % wikiutil.escape(url, True)) + + # Set body to the user interface language and direction + bodyattr.append(' %s' % self.ui_lang_attr()) + + body_onload = keywords.get('body_onload', '') + if body_onload: + bodyattr.append(''' onload="%s"''' % body_onload) + output.append('\n\n' % ''.join(bodyattr)) + + # Output ----------------------------------------------------------- + + # If in print mode, start page div and emit the title + if keywords.get('print_mode', 0): + d = { + 'title_text': text, + 'page': page, + 'page_name': pagename or '', + 'rev': rev, + } + request.themedict = d + output.append(self.startPage()) + output.append(self.interwiki(d)) + output.append(self.title(d)) + + # In standard mode, emit theme.header + else: + exists = pagename and page.exists(includeDeleted=True) + # prepare dict for theme code: + d = { + 'theme': self.name, + 'script_name': scriptname, + 'title_text': text, + 'logo_string': request.cfg.logo_string, + 'site_name': request.cfg.sitename, + 'page': page, + 'rev': rev, + 'pagesize': pagename and page.size() or 0, + # exists checked to avoid creation of empty edit-log for non-existing pages + 'last_edit_info': exists and page.lastEditInfo() or '', + 'page_name': pagename or '', + 'page_find_page': page_find_page, + 'page_front_page': page_front_page, + 'home_page': home_page, + 'page_help_contents': page_help_contents, + 'page_help_formatting': page_help_formatting, + 'page_parent_page': page_parent_page, + 'page_title_index': page_title_index, + 'page_word_index': page_word_index, + 'user_name': request.user.name, + 'user_valid': request.user.valid, + 'msg': self._status, + 'trail': keywords.get('trail', None), + # Discontinued keys, keep for a while for 3rd party theme developers + 'titlesearch': 'use self.searchform(d)', + 'textsearch': 'use self.searchform(d)', + 'navibar': ['use self.navibar(d)'], + 'available_actions': ['use self.request.availableActions(page)'], + } + + # add quoted versions of pagenames + newdict = {} + for key in d: + if key.startswith('page_'): + if not d[key] is None: + newdict['q_'+key] = wikiutil.quoteWikinameURL(d[key]) + else: + newdict['q_'+key] = None + d.update(newdict) + request.themedict = d + + # now call the theming code to do the rendering + if keywords.get('editor_mode', 0): + output.append(self.editorheader(d)) + else: + output.append(self.header(d)) + + # emit it + request.write(''.join(output)) + output = [] + request.flush() + self._send_title_called = True + + def send_footer(self, pagename, **keywords): + """ + Output the page footer. + + @param pagename: WikiName of the page + @keyword print_mode: true, when page is displayed in Print mode + """ + request = self.request + d = request.themedict + + # Emit end of page in print mode, or complete footer in standard mode + if keywords.get('print_mode', 0): + request.write(self.pageinfo(d['page'])) + request.write(self.endPage()) + else: + request.write(self.footer(d, **keywords)) + + # stuff moved from request.py + def send_closing_html(self): + """ generate timing info html and closing html tag, + everyone calling send_title must call this at the end to close + the body and html tags. + """ + request = self.request + + # as this is the last chance to emit some html, we stop the clocks: + request.clock.stop('run') + request.clock.stop('total') + + # Close html code + if request.cfg.show_timings and request.action != 'print': + request.write('
      \n') + for t in request.clock.dump(): + request.write('
    • %s
    • \n' % t) + request.write('
    \n') + #request.write('' % repr(request.user.auth_method)) + request.write('\n\n\n') + + diff --git a/theme/debwiki.py b/theme/debwiki.py new file mode 100644 index 0000000..5529bb3 --- /dev/null +++ b/theme/debwiki.py @@ -0,0 +1,324 @@ +# -*- coding: iso-8859-1 -*- +""" + MoinMoin - Debian theme + + @copyright: 2003-2005 Nir Soffer, Thomas Waldmann + @license: GNU GPL, see COPYING for details. + theme modified by Kalle Soderman +""" + +from MoinMoin.theme import ThemeBase +from MoinMoin import wikiutil +from MoinMoin.Page import Page + +class Theme(ThemeBase): + + name = "debwiki" + + _ = lambda x: x # We don't have gettext at this moment, so we fake it + icons = { + # key alt icon filename w h + # FileAttach + 'attach': ("%(attach_count)s", "moin-attach.png", 16, 16), + 'info': ("[INFO]", "moin-info.png", 16, 16), + 'attachimg': (_("[ATTACH]"), "attach.png", 32, 32), + # RecentChanges + 'rss': (_("[RSS]"), "moin-rss.png", 16, 16), + 'deleted': (_("[DELETED]"), "moin-deleted.png", 16, 16), + 'updated': (_("[UPDATED]"), "moin-updated.png", 16, 16), + 'renamed': (_("[RENAMED]"), "moin-renamed.png", 16, 16), + 'conflict': (_("[CONFLICT]"), "moin-conflict.png", 16, 16), + 'new': (_("[NEW]"), "moin-new.png", 16, 16), + 'diffrc': (_("[DIFF]"), "moin-diff.png", 16, 16), + # General + 'bottom': (_("[BOTTOM]"), "moin-bottom.png", 16, 16), + 'top': (_("[TOP]"), "moin-top.png", 16, 16), + 'www': ("[WWW]", "moin-www.png", 16, 16), + 'mailto': ("[MAILTO]", "moin-email.png", 16, 16), + 'news': ("[NEWS]", "moin-news.png", 16, 16), + 'telnet': ("[TELNET]", "moin-telnet.png", 16, 16), + 'ftp': ("[FTP]", "moin-ftp.png", 16, 16), + 'file': ("[FILE]", "moin-ftp.png", 16, 16), + # search forms + 'searchbutton': ("[?]", "moin-search.png", 16, 16), + 'interwiki': ("[%(wikitag)s]", "moin-inter.png", 16, 16), + + # smileys (this is CONTENT, but good looking smileys depend on looking + # adapted to the theme background color and theme style in general) + #vvv == vvv this must be the same for GUI editor converter + 'X-(': ("X-(", 'angry.png', 16, 16), + ':D': (":D", 'biggrin.png', 16, 16), + '<:(': ("<:(", 'frown.png', 16, 16), + ':o': (":o", 'redface.png', 16, 16), + ':(': (":(", 'sad.png', 16, 16), + ':)': (":)", 'smile.png', 16, 16), + 'B)': ("B)", 'smile2.png', 16, 16), + ':))': (":))", 'smile3.png', 16, 16), + ';)': (";)", 'smile4.png', 16, 16), + '/!\\': ("/!\\", 'alert.png', 16, 16), + '': ("", 'attention.png', 16, 16), + '(!)': ("(!)", 'idea.png', 16, 16), + ':-?': (":-?", 'tongue.png', 16, 16), + ':\\': (":\\", 'ohwell.png', 16, 16), + '>:>': (">:>", 'devil.png', 16, 16), + '|)': ("|)", 'tired.png', 16, 16), + ':-(': (":-(", 'sad.png', 16, 16), + ':-)': (":-)", 'smile.png', 16, 16), + 'B-)': ("B-)", 'smile2.png', 16, 16), + ':-))': (":-))", 'smile3.png', 16, 16), + ';-)': (";-)", 'smile4.png', 16, 16), + '|-)': ("|-)", 'tired.png', 16, 16), + '(./)': ("(./)", 'checkmark.png', 16, 16), + '{OK}': ("{OK}", 'thumbs-up.png', 16, 16), + '{X}': ("{X}", 'icon-error.png', 16, 16), + '{i}': ("{i}", 'icon-info.png', 16, 16), + '{1}': ("{1}", 'prio1.png', 15, 13), + '{2}': ("{2}", 'prio2.png', 15, 13), + '{3}': ("{3}", 'prio3.png', 15, 13), + '{*}': ("{*}", 'star_on.png', 16, 16), + '{o}': ("{o}", 'star_off.png', 16, 16), + } + del _ + def header(self, d, **kw): + """ Assemble wiki header + + @param d: parameter dictionary + @rtype: unicode + @return: page header html + """ + html = [ + # Pre header custom html + self.emit_custom_html(self.cfg.page_header1), + + # Header + u'', + + # Post header custom html (not recommended) + self.emit_custom_html(self.cfg.page_header2), + + # Start of page + self.startPage(), + ] + return u'\n'.join(html) + + def editorheader(self, d, **kw): + """ Assemble wiki header for editor + + @param d: parameter dictionary + @rtype: unicode + @return: page header html + """ + html = [ + # Pre header custom html + self.emit_custom_html(self.cfg.page_header1), + + # Header + u'', + + # Post header custom html (not recommended) + self.emit_custom_html(self.cfg.page_header2), + + # Start of page + self.startPage(), + ] + return u'\n'.join(html) + + def footer(self, d, **keywords): + """ Assemble wiki footer + + @param d: parameter dictionary + @keyword ...:... + @rtype: unicode + @return: page footer html + """ + page = d['page'] + html = [ + # End of page + self.pageinfo(page), + self.endPage(), + + # Pre footer custom html (not recommended!) + self.emit_custom_html(self.cfg.page_footer1), + + # Footer + u'', + + # Post footer custom html + self.emit_custom_html(self.cfg.page_footer2), + ] + return u'\n'.join(html) + + def title(self, d): + """ Assemble the title (now using breadcrumbs) + + @param d: parameter dictionary + @rtype: string + @return: title html + """ + _ = self.request.getText + content = [] + if d['title_text'] == d['page'].split_title(): # just showing a page, no action + curpage = '' + segments = d['page_name'].split('/') # was: title_text + for s in segments[:-1]: + curpage += s + content.append(Page(self.request, curpage).link_to(self.request, s)) + curpage += '/' + link_text = segments[-1] + link_title = _('Click to do a full-text search for this title') + link_query = { + 'action': 'fullsearch', + 'value': 'linkto:"%s"' % d['page_name'], + 'context': '180', + } + # we dont use d['title_link'] any more, but make it ourselves: + link = d['page'].link_to(self.request, link_text, querystr=link_query, title=link_title, css_class='backlink', rel='nofollow') + content.append(link) + else: + content.append(wikiutil.escape(d['title_text'])) + + location_html = u'/'.join(content) + html = u'%s' % location_html + return html + + def username(self, d): + """ Assemble the username / userprefs link + + @param d: parameter dictionary + @rtype: unicode + @return: username html + """ + request = self.request + _ = request.getText + + userlinks = [] + # Add username/homepage link for registered users. We don't care + # if it exists, the user can create it. + if request.user.valid and request.user.name: + interwiki = wikiutil.getInterwikiHomePage(request) + name = request.user.name + aliasname = request.user.aliasname + if not aliasname: + aliasname = name + title = "%s @ %s" % (aliasname, interwiki[0]) + # link to (interwiki) user homepage + homelink = (request.formatter.interwikilink(1, title=title, id="userhome", generated=True, *interwiki) + + request.formatter.text(name) + + request.formatter.interwikilink(0, title=title, id="userhome", *interwiki)) + userlinks.append(homelink) + # link to userprefs action + if 'userprefs' not in self.request.cfg.actions_excluded: + userlinks.append(d['page'].link_to(request, text=_('Settings'), + querystr={'action': 'userprefs'}, id='userprefs', rel='nofollow')) + + if request.user.valid: + if request.user.auth_method in request.cfg.auth_can_logout: + userlinks.append(d['page'].link_to(request, text=_('Logout'), + querystr={'action': 'logout', 'logout': 'logout'}, id='logout', rel='nofollow')) + else: + query = {'action': 'login'} + # special direct-login link if the auth methods want no input + if request.cfg.auth_login_inputs == ['special_no_input']: + query['login'] = '1' + if request.cfg.auth_have_login: + userlinks.append(d['page'].link_to(request, text=_("Login"), + querystr=query, id='login', rel='nofollow')) + + userlinks_html = u' | '.join(userlinks) + html = u'
    %s
    ' % userlinks_html + return html + + def trail(self, d): + """ Assemble page trail + + @param d: parameter dictionary + @rtype: unicode + @return: trail html + """ + request = self.request + user = request.user + html = '' + if not user.valid or user.show_page_trail: + trail = user.getTrail() + if trail: + items = [] + for pagename in trail: + try: + interwiki, page = wikiutil.split_interwiki(pagename) + if interwiki != request.cfg.interwikiname and interwiki != 'Self': + link = (self.request.formatter.interwikilink(True, interwiki, page) + + self.shortenPagename(page) + + self.request.formatter.interwikilink(False, interwiki, page)) + items.append(link) + continue + else: + pagename = page + + except ValueError: + pass + page = Page(request, pagename) + title = page.split_title() + title = self.shortenPagename(title) + link = page.link_to(request, title) + items.append(link) + html = u'
    %s
    ' % u'/'.join(items) + return html + + def interwiki(self, d): + """ Assemble the interwiki name display, linking to page_front_page + + @param d: parameter dictionary + @rtype: string + @return: interwiki html + """ + if self.request.cfg.show_interwiki: + page = wikiutil.getFrontPage(self.request) + text = self.request.cfg.interwikiname or 'Self' + link = page.link_to(self.request, text=text, rel='nofollow') + html = u'%s: ' % link + else: + html = u'' + return html + +def execute(request): + """ + Generate and return a theme object + + @param request: the request object + @rtype: MoinTheme + @return: Theme object + """ + return Theme(request) + diff --git a/wikiconfig.py.debwiki b/wikiconfig.py.debwiki new file mode 100644 index 0000000..df5b982 --- /dev/null +++ b/wikiconfig.py.debwiki @@ -0,0 +1,48 @@ +# -*- coding: iso-8859-1 -*- +"""MoinMoin Desktop Edition (MMDE) - Configuration + +ONLY to be used for MMDE - if you run a personal wiki on your notebook or PC. + +This is NOT intended for internet or server or multiuser use due to relaxed security settings! +""" +import sys, os +from MoinMoin.config.multiconfig import DefaultConfig + + +class LocalConfig(DefaultConfig): + # vvv DON'T TOUCH THIS EXCEPT IF YOU KNOW WHAT YOU DO vvv + moinmoin_dir = os.path.abspath(os.path.normpath(os.path.dirname(sys.argv[0]))) + data_dir = os.path.join(moinmoin_dir, 'wiki', 'data') + data_underlay_dir = os.path.join(moinmoin_dir, 'wiki', 'underlay') + + # DesktopEdition = True # give all local users full powers + acl_rights_default = u"All:read,write,delete,revert,admin" + surge_action_limits = None # no surge protection + sitename = u'Debian Wiki' + #logo_string = u'Debian' + page_front_page = u'FrontPage' # change to some better value + # ^^^ DON'T TOUCH THIS EXCEPT IF YOU KNOW WHAT YOU DO ^^^ + + + # Add your configuration items here. + + interwikiname = u'DebianWiki' + theme_default = u'debwiki' + page_header1 = '' + +# DEVELOPERS! Do not add your configuration items there, +# you could accidentally commit them! Instead, create a +# wikiconfig_local.py file containing this: +# +# from wikiconfig import LocalConfig +# +# class Config(LocalConfig): +# configuration_item_1 = 'value1' +# + +try: + from wikiconfig_local import Config +except ImportError, err: + if not str(err).endswith('wikiconfig_local'): + raise + Config = LocalConfig