diff --git a/README.md b/README.md index af82822..8ae6040 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,7 @@ An article - A template can include other templates, ten levels deep at most; a template that includes itself, directly or through another template, shows an error where the loop is (it cannot stop its own recursion with `{{#if:}}`, as on Wikipedia). A call to a template that does not exist is a red link to `Template:Name`. - The text of a template is parsed like article text, so it can use BBCode, `[[links]]`, headings and tables, and nothing an article could not. - The page of a template shows its documentation (what is inside ``, with its calls worked out, so it can show examples), then **Template text**: the text an article gets, as it is written and not worked out, with how many articles use it. `` text is left off the page. **What links here** lists the articles that use the template. +- **Templates** at `/wiki/templates`, linked from the overview, lists every template A to Z with its short description (the article's description field), how many articles use it, and when it was last edited. - Like headings and tables, this works in wiki articles only; in a forum post `{{Name}}` stays plain text. The first letter of a template name is not case-sensitive (`{{out of date}}` finds `Template:Out of date`). - **Parser functions** decide what a template shows. Only the part that is chosen is worked out, so the branch that is not taken can hold anything. diff --git a/config/routing.yml b/config/routing.yml index a741e24..188d0c3 100644 --- a/config/routing.yml +++ b/config/routing.yml @@ -12,6 +12,10 @@ phpbbmodders_wiki_recent_changes: path: /wiki/recent-changes defaults: { _controller: phpbbmodders.wiki.recent_changes:page } +phpbbmodders_wiki_templates: + path: /wiki/templates + defaults: { _controller: phpbbmodders.wiki.template_list:page } + phpbbmodders_wiki_contributions: path: /wiki/contributions/{username} defaults: { _controller: phpbbmodders.wiki.contributions:view } diff --git a/config/services.yml b/config/services.yml index 331b163..0522f6a 100644 --- a/config/services.yml +++ b/config/services.yml @@ -38,6 +38,20 @@ services: - '%core.root_path%' - '%core.php_ext%' + phpbbmodders.wiki.template_list: + class: phpbbmodders\wiki\controller\template_list + arguments: + - '@auth' + - '@config' + - '@dbal.conn' + - '@controller.helper' + - '@pagination' + - '@request' + - '@template' + - '@user' + - '@phpbbmodders.wiki.links' + - '%tables.wiki.article%' + phpbbmodders.wiki.contributions: class: phpbbmodders\wiki\controller\contributions arguments: diff --git a/controller/template_list.php b/controller/template_list.php new file mode 100644 index 0000000..b349984 --- /dev/null +++ b/controller/template_list.php @@ -0,0 +1,146 @@ +auth = $auth; + $this->config = $config; + $this->db = $db; + $this->helper = $helper; + $this->pagination = $pagination; + $this->request = $request; + $this->template = $template; + $this->user = $user; + $this->links = $links; + $this->article_table = $article_table; + } + + /** + * SQL condition for the live version of a template: approved, and not + * replaced by a newer approved version. + * + * @return string + */ + protected function live_template_where() + { + return 'a.article_approved = 1 + AND a.article_url ' . $this->db->sql_like_expression(\phpbbmodders\wiki\wiki\templates::PREFIX . $this->db->get_any_char()) . ' + AND NOT EXISTS ( + SELECT 1 FROM ' . $this->article_table . ' b + WHERE b.article_url = a.article_url + AND b.article_approved = 1 + AND (b.article_last_edit > a.article_last_edit + OR (b.article_last_edit = a.article_last_edit AND b.article_id > a.article_id)))'; + } + + /** + * The templates page. + * + * @return \Symfony\Component\HttpFoundation\Response + */ + public function page() + { + $this->user->add_lang_ext('phpbbmodders/wiki', 'common'); + + if (!$this->auth->acl_get('u_wiki_view')) + { + trigger_error('NOT_AUTHORISED'); + } + + $sql = 'SELECT COUNT(a.article_id) AS total + FROM ' . $this->article_table . ' a + WHERE ' . $this->live_template_where(); + $result = $this->db->sql_query($sql); + $total = (int) $this->db->sql_fetchfield('total'); + $this->db->sql_freeresult($result); + + $per_page = max(1, (int) $this->config['topics_per_page']); + $start = $this->pagination->validate_start($this->request->variable('start', 0), $per_page, $total); + + $sql = 'SELECT a.article_id, a.article_title, a.article_url, a.article_description, a.article_last_edit + FROM ' . $this->article_table . ' a + WHERE ' . $this->live_template_where() . ' + ORDER BY a.article_title ASC, a.article_id ASC'; + $result = $this->db->sql_query_limit($sql, $per_page, $start); + while ($row = $this->db->sql_fetchrow($result)) + { + $this->template->assign_block_vars('templates', array( + 'NAME' => substr($row['article_url'], strlen(\phpbbmodders\wiki\wiki\templates::PREFIX)), + 'DESCRIPTION' => $row['article_description'], + 'USED_ON' => count($this->links->what_links_here($row['article_url'])), + 'EDIT_TIME' => $this->user->format_date($row['article_last_edit']), + 'U_TEMPLATE' => $this->helper->route('phpbbmodders_wiki_article', array('article' => $row['article_url'])), + )); + } + $this->db->sql_freeresult($result); + + $this->template->assign_block_vars('navlinks', array( + 'FORUM_NAME' => $this->user->lang('WIKI'), + 'U_VIEW_FORUM' => $this->helper->route('phpbbmodders_wiki_index', array()), + )); + + $this->pagination->generate_template_pagination($this->helper->route('phpbbmodders_wiki_templates', array()), 'pagination', 'start', $total, $per_page, $start); + + $this->template->assign_vars(array( + 'TOTAL_ITEMS' => $this->user->lang('TOTAL_ITEMS', $total), + )); + + return $this->helper->render('template_list.html', $this->user->lang('WIKI_TEMPLATES')); + } +} diff --git a/docs/TODO/todo-wiki-markup.md b/docs/TODO/todo-wiki-markup.md index 42e7eee..ac73152 100644 --- a/docs/TODO/todo-wiki-markup.md +++ b/docs/TODO/todo-wiki-markup.md @@ -165,7 +165,7 @@ out. Still to do: functions per article. Add the cache only if articles with hundreds of calls become common. - A template call holds other calls in its parameters three levels deep, and a default value holds one level of `{{template}}`; deeper nesting stays text. -- A list of templates and a "Template" start-point in the article picker. +- A "Start from" choice for templates in the article picker. A set of ready-made templates, adapted from Wikipedia's, is planned as a separate repository: [Starter templates repository](todo-wiki-templates-repo.md). diff --git a/event/listener.php b/event/listener.php index 55d8726..283c56f 100644 --- a/event/listener.php +++ b/event/listener.php @@ -174,6 +174,7 @@ public function page_header($event) $this->template->assign_vars(array( 'U_WIKI' => $this->helper->route('phpbbmodders_wiki_index', array()), 'U_WIKI_RECENT_CHANGES' => $this->helper->route('phpbbmodders_wiki_recent_changes', array()), + 'U_WIKI_TEMPLATES' => $this->helper->route('phpbbmodders_wiki_templates', array()), 'U_WIKI_FEED_RSS' => \phpbbmodders\wiki\wiki\feed::offers($feed_setting, \phpbbmodders\wiki\wiki\feed::RSS) ? $this->helper->route('phpbbmodders_wiki_recent_changes_feed', array('_format' => 'rss')) : '', 'U_WIKI_FEED_ATOM' => \phpbbmodders\wiki\wiki\feed::offers($feed_setting, \phpbbmodders\wiki\wiki\feed::ATOM) ? $this->helper->route('phpbbmodders_wiki_recent_changes_feed', array('_format' => 'atom')) : '', 'WIKI_ICON_CLASSES' => \phpbbmodders\wiki\wiki\icon::classes(isset($this->config['wiki_icon']) ? $this->config['wiki_icon'] : \phpbbmodders\wiki\wiki\icon::DEFAULT_ICON), diff --git a/language/en/common.php b/language/en/common.php index 83ba920..de79016 100644 --- a/language/en/common.php +++ b/language/en/common.php @@ -106,6 +106,12 @@ 'WIKI_NOW_WATCHING' => 'You are now watching this article. You will be notified when a new version goes live.', 'WIKI_NO_LONGER_WATCHING' => 'You are no longer watching this article.', 'WIKI_RECENT_CHANGES' => 'Recent changes', + 'WIKI_TEMPLATES' => 'Templates', + 'WIKI_TEMPLATES_EXPLAIN' => 'Every template of the wiki, A to Z. A template is an article called “Template:Name”; write {{Name}} in an article to use it.', + 'WIKI_TEMPLATES_NONE' => 'There are no templates yet.', + 'WIKI_TEMPLATE' => 'Template', + 'WIKI_TEMPLATE_DESCRIPTION' => 'Description', + 'WIKI_TEMPLATE_USED_IN' => 'Used in', 'WIKI_RECENT_CHANGES_EXPLAIN' => 'Every version saved to the wiki that is or was live, newest first.', 'WIKI_FEED_RSS_LINK' => 'RSS feed', 'WIKI_FEED_ATOM_LINK' => 'Atom feed', diff --git a/styles/prosilver/template/overview.html b/styles/prosilver/template/overview.html index b9333f8..26ea4da 100644 --- a/styles/prosilver/template/overview.html +++ b/styles/prosilver/template/overview.html @@ -2,6 +2,7 @@

{L_OVERVIEW}

{L_WIKI_RECENT_CHANGES} + • {L_WIKI_TEMPLATES} • {L_WIKI_FEED_RSS_LINK} • {L_WIKI_FEED_ATOM_LINK}

diff --git a/styles/prosilver/template/template_list.html b/styles/prosilver/template/template_list.html new file mode 100644 index 0000000..52148f3 --- /dev/null +++ b/styles/prosilver/template/template_list.html @@ -0,0 +1,44 @@ + +

{L_WIKI_TEMPLATES}

+

{L_WIKI_TEMPLATES_EXPLAIN}

+ +
+
+ + + + + + + + + + + + + + + + + + + +
{L_WIKI_TEMPLATE}{L_WIKI_TEMPLATE_DESCRIPTION}{L_WIKI_TEMPLATE_USED_IN}{L_LAST_EDIT}
{templates.NAME}{templates.DESCRIPTION}{templates.USED_ON}{templates.EDIT_TIME}
+
+
+ +

{L_WIKI_TEMPLATES_NONE}

+ + +
+ +
+ +