diff --git a/action.php b/action.php
index 9f8a1e0..83bee92 100644
--- a/action.php
+++ b/action.php
@@ -7,7 +7,7 @@ class action_plugin_pagequery extends DokuWiki_Action_Plugin {
/**
* Register the eventhandlers
*/
- function register(&$controller) {
+ function register(Doku_Event_Handler $controller) {
$controller->register_hook('TOOLBAR_DEFINE', 'AFTER', $this, 'insert_button', array ());
}
diff --git a/inc/pagequery.php b/inc/pagequery.php
index 8f3c253..a7c9969 100644
--- a/inc/pagequery.php
+++ b/inc/pagequery.php
@@ -1,13 +1,12 @@
lang = $lang;
@@ -35,11 +34,19 @@ function render_as_empty($query, $error = '') {
function render_as_html($layout, $sorted_results, $opt, $count) {
+ $this->snippet_cnt = $opt['snippet']['count'];
$render_type = '_render_as_html_' . $layout;
return $this->$render_type($sorted_results, $opt, $count);
}
-
+ /**
+ * Used by the render_as_html_table function below
+ * **DEPRECATED**
+ *
+ * @param $sorted_results
+ * @param $ratios
+ * @return int
+ */
private function _adjusted_height($sorted_results, $ratios) {
// ratio of different heading heights (%), to ensure more even use of columns (h1 -> h6)
$adjusted_height = 0;
@@ -53,7 +60,8 @@ private function _adjusted_height($sorted_results, $ratios) {
/**
* Render the final pagequery results list as HTML, indented and in columns as required.
*
- * DEPRECATED --- I would like to scrap this ASAP (old browsers only).
+ * **DEPRECATED** --- I would like to scrap this ASAP (old browsers only).
+ * It's complicated and it's hard to maintain.
*
* @param array $sorted_results
* @param array $opt
@@ -109,7 +117,7 @@ protected function _render_as_html_table($sorted_results, $opt, $count) {
// now render the pagequery list
foreach ($sorted_results as $line) {
- list($level, $name, $id, $_, $abstract, $display) = $line;
+ list($level, $name, $id, $_, $abstract, $display, $thumbnail) = $line;
$heading = '';
$is_heading = ($level > 0);
@@ -152,11 +160,14 @@ protected function _render_as_html_table($sorted_results, $opt, $count) {
if ( ! $prev_was_heading) {
$render .= '' . DOKU_LF;
}
+ if ($opt['nstitle'] && ! empty($display)) {
+ $heading = $display;
+ }
if ($opt['proper'] == 'header' || $opt['proper'] == 'both') {
$heading = $this->_proper($heading);
}
if ( ! empty($id)) {
- $heading = $this->_html_wikilink($id, $heading, '', $opt, false, true);
+ $heading = $this->_html_wikilink($id, $heading, '', $thumbnail, $opt, false, true);
}
$render .= '' . $heading . '' . DOKU_LF;
$prev_was_heading = true;
@@ -170,7 +181,7 @@ protected function _render_as_html_table($sorted_results, $opt, $count) {
if ($opt['proper'] == 'name' || $opt['proper'] == 'both') {
$display = $this->_proper($display);
}
- $link = $this->_html_wikilink($id, $display, $abstract, $opt);
+ $link = $this->_html_wikilink($id, $display, $abstract, $thumbnail, $opt);
$render .= $link;
$prev_was_heading = false;
}
@@ -201,53 +212,35 @@ protected function _render_as_html_table($sorted_results, $opt, $count) {
*/
protected function _render_as_html_column($sorted_results, $opt, $count) {
- $render = '';
$prev_was_heading = false;
$cont_level = 1;
$is_first = true;
-
- $fontsize = '';
- $outer_border = '';
- $inner_border = '';
- $show_count = '';
- $label = '';
- $show_jump = '';
- $list_style = '';
-
- // A fixed anchor to jump back to at top
- $top_id = 'top-' . mt_rand();
+ $top_id = 'top-' . mt_rand(); // A fixed anchor at top to jump back to
// CSS for the various display options
- if ( ! empty($opt['fontsize'])) {
- $fontsize = 'font-size:' . $opt['fontsize'];
- }
- if ($opt['border'] == 'outside' || $opt['border'] == 'both') {
- $outer_border = 'border';
- }
- if ($opt['border'] == 'inside'|| $opt['border'] == 'both') {
- $inner_border = 'inner-border" ';
- }
- if ($opt['showcount'] == true) {
- $show_count = '
' . $count . ' ∞
' . DOKU_LF;
- }
- if ($opt['label'] != '') {
- $label = '' . $count . ' ∞
' . DOKU_LF : '';
+ $label = ($opt['label'] != '') ?
+ '' . DOKU_LF;
$render .= $show_count . $show_jump . $label . DOKU_LF;
$render .= '
' . DOKU_LF;
@@ -312,28 +311,41 @@ protected function _render_as_html_column($sorted_results, $opt, $count) {
* @param bool $raw => non-formatted (no html)
* @return string
*/
- private function _html_wikilink($id, $display, $abstract, $opt, $track_snippets = true, $raw = false) {
- static $snippet_cnt = 0;
+ private function _html_wikilink($id, $display, $abstract, $thumbnail, $opt, $track_snippets = true, $raw = false) {
+ global $INFO;
- if ($track_snippets) {
- $snippet_cnt++;
- }
$id = (strpos($id, ':') === false) ? ':' . $id : $id; // : needed for root pages (root level)
$link = html_wikilink($id, $display);
$type = $opt['snippet']['type'];
$inline = '';
$after = '';
-
- $count = $opt['snippet']['count'];
- $skip_snippet = ($count > 0 && $snippet_cnt >= $count);
+ $thumbnail_html = '';
+
+ if ( !empty( $thumbnail ) && !empty( $opt[ 'thumbnail' ] ) ) {
+ // Build the array of necessary data
+ $thumbnail_data = array(
+ 'src' => $thumbnail,
+ 'title' => $id,
+ 'align' => $opt['thumbnail']['align'],
+ 'width' => $opt['thumbnail']['width'],
+ 'height' => $opt['thumbnail']['height'],
+ 'cache' => 'cache',
+ );
+ // Check if we are dealing with an internal image
+ if ( !media_isexternal( $thumbnail ) ) {
+ $thumbnail_data['type'] = 'internalmedia';
+ }
+ // Get the link and image
+ $thumbnail_html = html_wikilink( $id, $thumbnail_data );
+ }
if ($type == 'tooltip') {
$tooltip = str_replace("\n\n", "\n", $abstract);
$tooltip = htmlentities($tooltip, ENT_QUOTES, 'UTF-8');
$link = $this->_add_tooltip($link, $tooltip);
- } elseif (in_array($type, array('quoted', 'plain', 'inline')) && ! $skip_snippet) {
+ } elseif (in_array($type, array('quoted', 'plain', 'inline')) && $this->snippet_cnt > 0) {
$short = $this->_shorten($abstract, $opt['snippet']['extent']);
$short = htmlentities($short, ENT_QUOTES, 'UTF-8');
if ( ! empty($short)) {
@@ -350,10 +362,16 @@ private function _html_wikilink($id, $display, $abstract, $opt, $track_snippets
}
$border = ($opt['underline']) ? 'border' : '';
+ if ( $id == $INFO['id'] ) {
+ $border .= ' current';
+ }
if ($raw) {
$wikilink = $link . $inline;
} else {
- $wikilink = '
' . $link . $inline . DOKU_LF . $after . '';
+ $wikilink = '' . $thumbnail_html . $link . $inline . DOKU_LF . $after . '';
+ }
+ if ($track_snippets) {
+ $this->snippet_cnt--;
}
return $wikilink;
}
@@ -378,12 +396,12 @@ private function _add_tooltip($link, $tooltip) {
*
* @param string $text
* @param string $extent c? = ? chars, w? = ? words, l? = ? lines, ~? = search up to text/char/symbol
- * @param string $more
+ * @param string $more symbol to show if more text
* @return string
*/
private function _shorten($text, $extent, $more = '... ') {
$elem = $extent[0];
- $cnt = substr($extent, 1);
+ $cnt = (int) substr($extent, 1);
switch ($elem) {
case 'c':
$result = substr($text, 0, $cnt);
@@ -418,12 +436,31 @@ private function _shorten($text, $extent, $more = '... ') {
private function _proper($id) {
$id = str_replace(':', ': ', $id); // make a little whitespace before words so ucwords can work!
$id = str_replace('_', ' ', $id);
- $id = ucwords($id);
+ $id = utf8_ucwords($id);
$id = str_replace(': ', ':', $id);
return $id;
}
+ /**
+ * a mb version of 'ucwords' that respects capitalised words
+ * does not work for hyphenated words (yet)
+ * **UNUSED**
+ */
+ private function _mb_ucwords($str) {
+ $result = array();
+ $words = mb_split('\s', $str);
+ foreach ($words as $word) {
+ if (mb_strtoupper($word) == $word) {
+ $result[] = $word;
+ } else {
+ $result[] = mb_convert_case($word, MB_CASE_TITLE, "UTF-8");
+ }
+ }
+ return implode(' ', $result);
+ }
+
+
/**
* Parse out the namespace, and convert to a regex for array search
*
@@ -544,7 +581,7 @@ function build_sorting_array($ids, $opt) {
case 'a':
case 'ab':
case 'abc':
- $value = $this->_first(strtolower($abc), strlen($key));
+ $value = $this->_first($abc, strlen($key));
break;
case 'name':
case 'title':
@@ -644,12 +681,17 @@ function build_sorting_array($ids, $opt) {
} elseif (isset($row[$display])) {
$display = $row[$display];
- // if all else fails then used the page name (always available)
+ // if all else fails then use the page name (always available)
} else {
$display = $row['name'];
}
$row['display'] = $display;
+ // Get the page's first image, if available
+ if ( isset( $meta['relation']['firstimage'] ) ) {
+ $row['thumbnail'] = $meta['relation']['firstimage'];
+ }
+
$cnt++;
}
@@ -754,9 +796,9 @@ private function _join_keys_if($delim, $arr) {
}
- // returns first $count letters from $text
+ // returns first $count letters from $text in lowercase
private function _first($text, $count) {
- $result = ($count > 0) ? utf8_substr($text, 0, $count) : '';
+ $result = ($count > 0) ? utf8_substr(utf8_strtolower($text), 0, $count) : '';
return $result;
}
@@ -1158,9 +1200,10 @@ private function _add_heading(&$results, &$sort_array, &$group_opts, $level, $id
if ($group_type === self::MGROUP_HEADING) {
$date_format = $group_opts['dformat'][$level];
if ( ! empty($date_format)) {
- // the real date is always the the '__realdate__' column (MGROUP_REALDATE)
+ // the real date is always the '__realdate__' column (MGROUP_REALDATE)
$cur = strftime($date_format, $sort_array[$idx][self::MGROUP_REALDATE]);
}
+ // args : $level, $name, $id, $_, $abstract, $display
$results[] = array($level + 1, $cur, '');
} elseif ($group_type === self::MGROUP_NAMESPACE) {
@@ -1171,12 +1214,19 @@ private function _add_heading(&$results, &$sort_array, &$group_opts, $level, $id
if ($cur_ns[$i] != $prev_ns[$i]) {
$hl = $level + $i + 1;
$id = implode(':', array_slice($cur_ns, 0, $i + 1)) . ':' . $conf['start'];
- $ns_start = (page_exists($id)) ? $id : '';
- $results[] = array($hl , $cur_ns[$i], $ns_start, '', '');
+ if (page_exists($id)) {
+ $ns_start = $id;
+ // allow the first heading to be used instead of page id/name
+ $display = p_get_metadata($id, 'title');
+ } else {
+ $ns_start = $display = '';
+ }
+ // args : $level, $name, $id, $_, $abstract, $display
+ $results[] = array($hl , $cur_ns[$i], $ns_start, '', '', $display);
}
}
}
}
}
-}
\ No newline at end of file
+}
diff --git a/lang/ja/lang.php b/lang/ja/lang.php
new file mode 100644
index 0000000..a7f2fb2
--- /dev/null
+++ b/lang/ja/lang.php
@@ -0,0 +1,13 @@
+[query;fulltext;sort=key:direction,key2:direction;group;limit=??;cols=?;inwords;proper]}} [..] = optional
url http://www.dokuwiki.org/plugin:pagequery
diff --git a/syntax.php b/syntax.php
index 4b12394..10aafbc 100644
--- a/syntax.php
+++ b/syntax.php
@@ -55,7 +55,7 @@ function connectTo($mode) {
*
* @link https://www.dokuwiki.org/plugin:pagequery See PageQuery page for full details
*/
- function handle($match, $state, $pos, &$handler) {
+ function handle($match, $state, $pos, Doku_Handler $handler) {
$opt = array();
$match = substr($match, 12, -2); // strip markup "{{pagequery>...}}"
@@ -91,9 +91,11 @@ function handle($match, $state, $pos, &$handler) {
$opt['sort'] = array(); // sort by various headings
$opt['spelldate'] = false; // spell out date headings in words where possible
$opt['underline'] = false; // faint underline below each link for clarity
+ $opt['nstitle'] = false; // internal use currently...
+ $opt['thumbnail'] = array(); // first image in page
foreach ($params as $param) {
- list($option, $value) = explode('=', $param);
+ list($option, $value) = $this->_keyvalue($param, '=');
switch ($option) {
case 'casesort':
case 'fullregex':
@@ -116,7 +118,7 @@ function handle($match, $state, $pos, &$handler) {
case 'filter':
$fields = explode(',', $value);
foreach ($fields as $field) {
- list($key, $expr) = explode(':', $field, 2);
+ list($key, $expr) = $this->_keyvalue($field);
// allow for a few common naming differences
switch ($key) {
case 'pagename':
@@ -198,6 +200,7 @@ function handle($match, $state, $pos, &$handler) {
case 'heading':
case 'firstheading':
$opt['display'] = 'title';
+ $opt['nstitle'] = true;
break;
case 'pageid':
case 'id':
@@ -206,6 +209,9 @@ function handle($match, $state, $pos, &$handler) {
default:
$opt['display'] = $value;
}
+ if (preg_match('/\{(title|heading|firstheading)\}/', $value)) {
+ $opt['nstitle'] = true;
+ }
break;
case 'layout':
if ( ! in_array($value, array('table', 'column'))) {
@@ -218,13 +224,47 @@ function handle($match, $state, $pos, &$handler) {
$opt['fontsize'] = $value;
}
break;
+ case 'thumbnail':
+ // Set defaults here
+ $opt['thumbnail'] = array( 'width' => 100, 'heigth' => null, 'align' => '' );
+
+ $thumb_details = explode( ',', strtolower( $value ) );
+ $thumb_details = array_slice( $thumb_details, 0, 2 ); // Allow a maximum of 2 arguments
+ $thumb_details = array_map( 'trim', $thumb_details );
+ foreach ( $thumb_details as $thumb_detail ) {
+ // Allow for full size images
+ if ( $thumb_detail == '0' || $thumb_detail == '0x0' ) {
+ $opt['thumbnail']['height'] = null;
+ $opt['thumbnail']['width'] = null;
+ }
+ // Determine image size (both width and height are given)
+ elseif ( strpos( $thumb_detail, 'x' ) ) {
+ $thumb_size = explode( 'x', $thumb_detail );
+ $thumb_size = array_map( 'intval', $thumb_size );
+ if ( $thumb_size[0] > 0 ) {
+ $opt['thumbnail']['width'] = $thumb_size[0];
+ }
+ if ( $thumb_size[1] > 0 ) {
+ $opt['thumbnail']['height'] = $thumb_size[1];
+ }
+ }
+ // Determine image size (only width is given)
+ elseif ( is_numeric( $thumb_detail ) && intval( $thumb_detail ) > 0 ) {
+ $opt['thumbnail']['width'] = intval( $thumb_detail );
+ }
+ // Determine image alignment
+ elseif ( in_array( $thumb_detail, array( 'center', 'left', 'right' ) ) ) {
+ $opt['thumbnail']['align'] = $thumb_detail;
+ }
+ }
+ break;
}
}
return $opt;
- }
+ }
- function render($mode, &$renderer, $opt) {
+ function render($mode, Doku_Renderer $renderer, $opt) {
if ( ! PHP_MAJOR_VERSION >= 5 && ! PHP_MINOR_VERSION >= 3) {
$renderer->doc .= "You must have PHP 5.3 or greater to use this pagequery plugin. Please upgrade PHP or use an older version of the plugin";
@@ -243,6 +283,7 @@ function render($mode, &$renderer, $opt) {
'no_results' => $this->getLang('no_results')
);
$pq = new PageQuery($lang);
+
$query = $opt['query'];
if ($mode == 'xhtml') {
@@ -306,7 +347,7 @@ function render($mode, &$renderer, $opt) {
$count = count($sort_array);
// and finally the grouping
- $keys = array('name', 'id', 'title', 'abstract', 'display');
+ $keys = array('name', 'id', 'title', 'abstract', 'display', 'thumbnail');
if ( ! $opt['group']) $group_opts = array();
$sorted_results = $pq->mgroup($sort_array, $keys, $group_opts);
@@ -324,5 +365,20 @@ function render($mode, &$renderer, $opt) {
return false;
}
}
+
+
+ /**
+ * Split a string into key => value parts.
+ *
+ * @param string $str
+ * @param string $delim
+ * @return array
+ */
+ private function _keyvalue($str, $delim = ':') {
+ $parts = explode($delim, $str);
+ $key = isset($parts[0]) ? $parts[0] : '';
+ $value = isset($parts[1]) ? $parts[1] : '';
+ return array($key, $value);
+ }
}