summaryrefslogtreecommitdiff
path: root/platform/www/lib/plugins/tag
diff options
context:
space:
mode:
Diffstat (limited to 'platform/www/lib/plugins/tag')
-rw-r--r--platform/www/lib/plugins/tag/COPYING340
-rw-r--r--platform/www/lib/plugins/tag/README10
-rw-r--r--platform/www/lib/plugins/tag/_test/topic_and_tagrefine.test.php107
-rw-r--r--platform/www/lib/plugins/tag/_test/topic_sort.test.php59
-rw-r--r--platform/www/lib/plugins/tag/_test/topic_tag.test.php36
-rw-r--r--platform/www/lib/plugins/tag/action.php138
-rw-r--r--platform/www/lib/plugins/tag/conf/default.php13
-rw-r--r--platform/www/lib/plugins/tag/conf/metadata.php20
-rw-r--r--platform/www/lib/plugins/tag/helper.php513
-rw-r--r--platform/www/lib/plugins/tag/images/tag-toolbar.pngbin0 -> 328 bytes
-rw-r--r--platform/www/lib/plugins/tag/images/tag.gifbin0 -> 111 bytes
-rw-r--r--platform/www/lib/plugins/tag/lang/ar/lang.php20
-rw-r--r--platform/www/lib/plugins/tag/lang/ar/settings.php31
-rw-r--r--platform/www/lib/plugins/tag/lang/be/lang.php18
-rw-r--r--platform/www/lib/plugins/tag/lang/be/settings.php29
-rw-r--r--platform/www/lib/plugins/tag/lang/bg/lang.php19
-rw-r--r--platform/www/lib/plugins/tag/lang/bg/settings.php30
-rw-r--r--platform/www/lib/plugins/tag/lang/ckb/lang.php18
-rw-r--r--platform/www/lib/plugins/tag/lang/ckb/settings.php29
-rw-r--r--platform/www/lib/plugins/tag/lang/cs/lang.php22
-rw-r--r--platform/www/lib/plugins/tag/lang/cs/settings.php31
-rw-r--r--platform/www/lib/plugins/tag/lang/cy/lang.php20
-rw-r--r--platform/www/lib/plugins/tag/lang/cy/settings.php29
-rw-r--r--platform/www/lib/plugins/tag/lang/da/lang.php20
-rw-r--r--platform/www/lib/plugins/tag/lang/da/settings.php30
-rw-r--r--platform/www/lib/plugins/tag/lang/de-informal/lang.php20
-rw-r--r--platform/www/lib/plugins/tag/lang/de-informal/settings.php30
-rw-r--r--platform/www/lib/plugins/tag/lang/de/lang.php22
-rw-r--r--platform/www/lib/plugins/tag/lang/de/settings.php31
-rw-r--r--platform/www/lib/plugins/tag/lang/el/lang.php18
-rw-r--r--platform/www/lib/plugins/tag/lang/el/settings.php29
-rw-r--r--platform/www/lib/plugins/tag/lang/en/lang.php23
-rw-r--r--platform/www/lib/plugins/tag/lang/en/settings.php32
-rw-r--r--platform/www/lib/plugins/tag/lang/eo/lang.php19
-rw-r--r--platform/www/lib/plugins/tag/lang/eo/settings.php30
-rw-r--r--platform/www/lib/plugins/tag/lang/es/lang.php21
-rw-r--r--platform/www/lib/plugins/tag/lang/es/settings.php31
-rw-r--r--platform/www/lib/plugins/tag/lang/fa/lang.php19
-rw-r--r--platform/www/lib/plugins/tag/lang/fa/settings.php29
-rw-r--r--platform/www/lib/plugins/tag/lang/fi/lang.php18
-rw-r--r--platform/www/lib/plugins/tag/lang/fi/settings.php29
-rw-r--r--platform/www/lib/plugins/tag/lang/fr/lang.php20
-rw-r--r--platform/www/lib/plugins/tag/lang/fr/settings.php33
-rw-r--r--platform/www/lib/plugins/tag/lang/he/lang.php18
-rw-r--r--platform/www/lib/plugins/tag/lang/he/settings.php29
-rw-r--r--platform/www/lib/plugins/tag/lang/hi/lang.php18
-rw-r--r--platform/www/lib/plugins/tag/lang/hi/settings.php29
-rw-r--r--platform/www/lib/plugins/tag/lang/hr/lang.php19
-rw-r--r--platform/www/lib/plugins/tag/lang/hr/settings.php29
-rw-r--r--platform/www/lib/plugins/tag/lang/hu/lang.php19
-rw-r--r--platform/www/lib/plugins/tag/lang/hu/settings.php31
-rw-r--r--platform/www/lib/plugins/tag/lang/id/lang.php18
-rw-r--r--platform/www/lib/plugins/tag/lang/id/settings.php29
-rw-r--r--platform/www/lib/plugins/tag/lang/it/lang.php18
-rw-r--r--platform/www/lib/plugins/tag/lang/it/settings.php29
-rw-r--r--platform/www/lib/plugins/tag/lang/ja/lang.php20
-rw-r--r--platform/www/lib/plugins/tag/lang/ja/settings.php30
-rw-r--r--platform/www/lib/plugins/tag/lang/ko/lang.php20
-rw-r--r--platform/www/lib/plugins/tag/lang/ko/settings.php29
-rw-r--r--platform/www/lib/plugins/tag/lang/nl/lang.php20
-rw-r--r--platform/www/lib/plugins/tag/lang/nl/settings.php31
-rw-r--r--platform/www/lib/plugins/tag/lang/pl/lang.php18
-rw-r--r--platform/www/lib/plugins/tag/lang/pl/settings.php29
-rw-r--r--platform/www/lib/plugins/tag/lang/pt-br/lang.php18
-rw-r--r--platform/www/lib/plugins/tag/lang/pt-br/settings.php32
-rw-r--r--platform/www/lib/plugins/tag/lang/pt/lang.php18
-rw-r--r--platform/www/lib/plugins/tag/lang/pt/settings.php29
-rw-r--r--platform/www/lib/plugins/tag/lang/ru/lang.php20
-rw-r--r--platform/www/lib/plugins/tag/lang/ru/settings.php30
-rw-r--r--platform/www/lib/plugins/tag/lang/sv/lang.php20
-rw-r--r--platform/www/lib/plugins/tag/lang/sv/settings.php30
-rw-r--r--platform/www/lib/plugins/tag/lang/tr/lang.php19
-rw-r--r--platform/www/lib/plugins/tag/lang/tr/settings.php29
-rw-r--r--platform/www/lib/plugins/tag/lang/uk/lang.php18
-rw-r--r--platform/www/lib/plugins/tag/lang/uk/settings.php29
-rw-r--r--platform/www/lib/plugins/tag/lang/vi/lang.php19
-rw-r--r--platform/www/lib/plugins/tag/lang/vi/settings.php29
-rw-r--r--platform/www/lib/plugins/tag/lang/zh-tw/lang.php21
-rw-r--r--platform/www/lib/plugins/tag/lang/zh-tw/settings.php32
-rw-r--r--platform/www/lib/plugins/tag/lang/zh/lang.php20
-rw-r--r--platform/www/lib/plugins/tag/lang/zh/settings.php30
-rw-r--r--platform/www/lib/plugins/tag/manager.dat2
-rw-r--r--platform/www/lib/plugins/tag/plugin.info.txt7
-rw-r--r--platform/www/lib/plugins/tag/script.js16
-rw-r--r--platform/www/lib/plugins/tag/style.css28
-rw-r--r--platform/www/lib/plugins/tag/syntax/count.php124
-rw-r--r--platform/www/lib/plugins/tag/syntax/searchtags.php281
-rw-r--r--platform/www/lib/plugins/tag/syntax/tag.php112
-rw-r--r--platform/www/lib/plugins/tag/syntax/tagpage.php90
-rw-r--r--platform/www/lib/plugins/tag/syntax/topic.php129
90 files changed, 3751 insertions, 0 deletions
diff --git a/platform/www/lib/plugins/tag/COPYING b/platform/www/lib/plugins/tag/COPYING
new file mode 100644
index 0000000..d60c31a
--- /dev/null
+++ b/platform/www/lib/plugins/tag/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/platform/www/lib/plugins/tag/README b/platform/www/lib/plugins/tag/README
new file mode 100644
index 0000000..8b25647
--- /dev/null
+++ b/platform/www/lib/plugins/tag/README
@@ -0,0 +1,10 @@
+====== Tag Plugin for DokuWiki ======
+
+All documentation for the Tag Plugin is available online at:
+
+ * http://dokuwiki.org/plugin:tag
+
+(c) 2005 - 2007 by Esther Brunner <wikidesign@gmail.com>
+(c) 2008 - 2009 by Gina Häußge, Michael Klier <dokuwiki@chimeric.de>
+(c) 2012 - 2013 by Michael Hamann and the tag plugin team <michael@content-space.de>
+See COPYING for license info.
diff --git a/platform/www/lib/plugins/tag/_test/topic_and_tagrefine.test.php b/platform/www/lib/plugins/tag/_test/topic_and_tagrefine.test.php
new file mode 100644
index 0000000..b466eb3
--- /dev/null
+++ b/platform/www/lib/plugins/tag/_test/topic_and_tagrefine.test.php
@@ -0,0 +1,107 @@
+<?php
+
+if (!defined('DOKU_INC')) die();
+
+/**
+ * Tests the tagRefine function of the tag plugin
+ */
+class plugin_tag_topic_and_tagrefine_test extends DokuWikiTest {
+ private $all_pages = array(
+ 'tagged_page' => array('id' => 'tagged_page'),
+ 'negative_page' => array('id' => 'negative_page'),
+ 'third_page' => array('id' => 'third_page')
+ );
+ public function setUp() {
+ $this->pluginsEnabled[] = 'tag';
+ parent::setUp();
+
+ saveWikiText(
+ 'tagged_page',
+ '{{tag>mytag test2tag}}', 'Test'
+ );
+ saveWikiText(
+ 'negative_page',
+ '{{tag>negative_tag mytag}}',
+ 'Test setup'
+ );
+ saveWikiText(
+ 'third_page',
+ '{{tag>third_tag}}',
+ 'Test setup'
+ );
+ idx_addPage('tagged_page');
+ idx_addPage('negative_page');
+ idx_addPage('third_page');
+ }
+
+ public function testEmptyTag() {
+ $this->assertTopicRefine(array('tagged_page', 'negative_page', 'third_page'), '');
+ }
+
+ public function testOnlyNegative() {
+ $this->assertTopicRefine(array('tagged_page', 'third_page'), '-negative_tag');
+ }
+
+ public function testMixed() {
+ $this->assertTopicRefine(array('tagged_page'), 'mytag -negative_tag');
+
+ }
+
+ public function testAnd() {
+ $this->assertTopicRefine(array('tagged_page'), '+mytag +test2tag');
+ }
+
+ public function testAndOr() {
+ $this->assertTopicRefine(array('tagged_page', 'third_page'), '+test2tag third_tag');
+ }
+
+ public function testOrAnd() {
+ $this->assertTopicRefine(array('tagged_page'), 'mytag +test2tag');
+ }
+
+ public function testRefineDoesntAdd() {
+ /** @var helper_plugin_tag $helper */
+ $helper = plugin_load('helper', 'tag');
+ $pages = $helper->tagRefine(array(), 'mytag');
+ $this->hasPages(array(), $pages, 'Refine with empty input array and "mytag" query: ');
+ }
+
+ /**
+ * Test if the getTopic and the tagRefine function with all pages as input both return the expected pages
+ *
+ * @param array $expected expected page ids
+ * @param string $query the query for the tagRefine/getTopic-functions
+ */
+ private function assertTopicRefine($expected, $query) {
+ /** @var helper_plugin_tag $helper */
+ $helper = plugin_load('helper', 'tag');
+ $pages = $helper->tagRefine($this->all_pages, $query);
+ $this->hasPages($expected, $pages, 'Refine: '.$query.': ');
+ $pages = $helper->getTopic('', '', $query);
+ $this->hasPages($expected, $pages, 'Topic: '.$query.': ');
+ }
+
+ /**
+ * Makes sure that all pages were found and not more
+ *
+ * @param array $expected List of page ids
+ * @param array $actual Result list from getTopic/tagRefine
+ * @param string $msg_prefix A prefix that is prepended to all messages
+ */
+ private function hasPages($expected, $actual, $msg_prefix = '') {
+ foreach ($expected as $id) {
+ $found = false;
+ foreach ($actual as $page) {
+ if ($page['id'] === $id) {
+ $found = true;
+ break;
+ }
+ }
+ $this->assertTrue($found, $msg_prefix.'Page '.$id.' expected but not found in the result');
+ }
+
+ foreach ($actual as $page) {
+ $this->assertTrue(in_array($page['id'], $expected), $msg_prefix.'Page '.$page['id'].' is in the result but wasn\'t expected');
+ }
+ }
+}
diff --git a/platform/www/lib/plugins/tag/_test/topic_sort.test.php b/platform/www/lib/plugins/tag/_test/topic_sort.test.php
new file mode 100644
index 0000000..aca59f4
--- /dev/null
+++ b/platform/www/lib/plugins/tag/_test/topic_sort.test.php
@@ -0,0 +1,59 @@
+<?php
+
+if (!defined('DOKU_INC')) die();
+
+/**
+ * Tests the tagRefine function of the tag plugin
+ */
+class plugin_tag_topic_sorting_test extends DokuWikiTest {
+ private $pages = array(
+ 'a',
+ 'aa',
+ 'a:a',
+ 'a:aa',
+ 'a:a:c',
+ 'a:a:b:a',
+ 'a:b:c'
+ );
+ /** @var helper_plugin_tag $helper */
+ private $helper;
+
+ public function setUp() {
+ global $conf;
+ $this->pluginsEnabled[] = 'tag';
+ parent::setUp();
+
+ $conf['plugin']['tag']['sortkey'] = 'ns';
+
+ $this->helper = plugin_load('helper', 'tag');
+
+
+ foreach ($this->pages as $page) {
+ saveWikiText(
+ $page,
+ '{{tag>mytag}}', 'Test'
+ );
+ idx_addPage($page);
+ }
+ }
+
+ public function test_ns_sort() {
+ $this->assertEquals($this->pages, $this->extract_ids($this->helper->getTopic('', null, 'mytag')));
+ }
+
+
+ /**
+ * Extract the id attribute of the supplied pages
+ *
+ * @param array $pages The pages that shall be used
+ * @return array The ids of the pages
+ */
+ private function extract_ids($pages) {
+ $result = array();
+ foreach ($pages as $page) {
+ $result[] = $page['id'];
+ }
+ return $result;
+ }
+
+}
diff --git a/platform/www/lib/plugins/tag/_test/topic_tag.test.php b/platform/www/lib/plugins/tag/_test/topic_tag.test.php
new file mode 100644
index 0000000..63908aa
--- /dev/null
+++ b/platform/www/lib/plugins/tag/_test/topic_tag.test.php
@@ -0,0 +1,36 @@
+<?php
+
+/**
+ * Tests the basic functionality of the tag and topic syntax
+ */
+class topic_tag_test extends DokuWikiTest {
+ function setup() {
+ $this->pluginsEnabled[] = 'tag';
+ $this->pluginsEnabled[] = 'pagelist';
+ parent::setup();
+ }
+
+ function test_topic_tag() {
+ saveWikiText(
+ 'tagged_page',
+ '{{tag>mytag test2tag}}', 'Test'
+ );
+ saveWikiText(
+ 'topic_page',
+ '{{topic>mytag}}'.DOKU_LF.DOKU_LF.'{{tag>topictag mytag}}'.DOKU_LF, 'Test'
+ );
+ idx_addPage('topic_page');
+ idx_addPage('tagged_page');
+ $this->assertContains('tag:topictag', p_wiki_xhtml('topic_page'), 'Page with tag syntax doesn\'t contain tag output');
+ $this->assertNotContains('tag:test2tag', p_wiki_xhtml('topic_page'), 'Page with tag and topic syntax tag which is listed in a page that is listed in the topic syntax but not on the page itself');
+ $this->assertContains('topic_page', p_wiki_xhtml('topic_page'), 'Page with topic and tag syntax doesn\'t list itself in the topic syntax');
+ $this->assertContains('tagged_page', p_wiki_xhtml('topic_page'), 'Page with topic syntax doesn\'t list matching page');
+ $this->assertContains('tag:mytag', p_wiki_xhtml('tagged_page'), 'Page with tag syntax doesn\'t contain tag output');
+ $this->assertContains('tag:test2tag', p_wiki_xhtml('tagged_page'), 'Page with tag syntax doesn\'t contain tag output');
+ $this->assertNotContains('tag:topictag', p_wiki_xhtml('tagged_page'), 'Page with tag syntax contains tag from a page in which it is listed in the topic syntax');
+ saveWikiText('tagged_page', '{{tag>test2tag}}', 'Deleted mytag');
+ $this->assertNotContains('tagged_page', p_wiki_xhtml('topic_page'), 'Page that no longer contains the tag is still listed in the topic syntax (caching problems?)');
+ $this->assertNotContains('tag:mytag', p_wiki_xhtml('tagged_page'), 'Removed tag is still listed in XHTML output');
+
+ }
+}
diff --git a/platform/www/lib/plugins/tag/action.php b/platform/www/lib/plugins/tag/action.php
new file mode 100644
index 0000000..d008628
--- /dev/null
+++ b/platform/www/lib/plugins/tag/action.php
@@ -0,0 +1,138 @@
+<?php
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Esther Brunner <wikidesign@gmail.com>
+ */
+
+/**
+ * Action part of the tag plugin, handles tag display and index updates
+ */
+class action_plugin_tag extends DokuWiki_Action_Plugin {
+
+ /**
+ * register the eventhandlers
+ *
+ * @param Doku_Event_Handler $contr
+ */
+ function register(Doku_Event_Handler $contr) {
+ $contr->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, '_handle_act', array());
+ $contr->register_hook('TPL_ACT_UNKNOWN', 'BEFORE', $this, '_handle_tpl_act', array());
+ $contr->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, '_handle_keywords', array());
+ if($this->getConf('toolbar_icon')) $contr->register_hook('TOOLBAR_DEFINE', 'AFTER', $this, 'insert_toolbar_button', array ());
+ $contr->register_hook('INDEXER_VERSION_GET', 'BEFORE', $this, '_indexer_version', array());
+ $contr->register_hook('INDEXER_PAGE_ADD', 'BEFORE', $this, '_indexer_index_tags', array());
+ }
+
+ /**
+ * Add a version string to the index so it is rebuilt
+ * whenever the stored data format changes.
+ */
+ function _indexer_version(Doku_Event $event, $param) {
+ global $conf;
+ $event->data['plugin_tag'] = '0.2.deaccent='.$conf['deaccent'];
+ }
+
+ /**
+ * Add all data of the subject metadata to the metadata index.
+ */
+ function _indexer_index_tags(Doku_Event $event, $param) {
+ /* @var helper_plugin_tag $helper */
+ if ($helper = $this->loadHelper('tag')) {
+ // make sure the tags are cleaned and no duplicate tags are added to the index
+ $tags = p_get_metadata($event->data['page'], 'subject');
+ if (!is_array($tags)) {
+ $event->data['metadata']['subject'] = array();
+ } else {
+ $event->data['metadata']['subject'] = $helper->_cleanTagList($tags);
+ }
+ }
+ }
+
+ /**
+ * catch tag action
+ *
+ * @author Michael Klier <chi@chimeric.de>
+ */
+ function _handle_act(Doku_Event $event, $param) {
+ if($event->data != 'showtag') return;
+ $event->preventDefault();
+ }
+
+ /**
+ * Display the tag page
+ *
+ * @param Doku_Event $event The TPL_ACT_UNKNOWN event
+ * @param array $param optional parameters (unused)
+ */
+ function _handle_tpl_act(Doku_Event $event, $param) {
+ global $lang;
+
+ if($event->data != 'showtag') return;
+ $event->preventDefault();
+
+ $tagns = $this->getConf('namespace');
+ $flags = explode(',', str_replace(" ", "", $this->getConf('pagelist_flags')));
+
+ $tag = trim(str_replace($this->getConf('namespace').':', '', $_REQUEST['tag']));
+ $ns = trim($_REQUEST['ns']);
+
+ /* @var helper_plugin_tag $helper */
+ if ($helper = $this->loadHelper('tag')) $pages = $helper->getTopic($ns, '', $tag);
+
+ if(!empty($pages)) {
+
+ // let Pagelist Plugin do the work for us
+ if ((!$pagelist = $this->loadHelper('pagelist'))) {
+ return false;
+ }
+
+ /* @var helper_plugin_pagelist $pagelist */
+ $pagelist->setFlags($flags);
+ $pagelist->startList();
+ foreach ($pages as $page) {
+ $pagelist->addPage($page);
+ }
+
+ print '<h1>TAG: ' . hsc(str_replace('_', ' ', $_REQUEST['tag'])) . '</h1>' . DOKU_LF;
+ print '<div class="level1">' . DOKU_LF;
+ print $pagelist->finishList();
+ print '</div>' . DOKU_LF;
+
+ } else {
+ print '<div class="level1"><p>' . $lang['nothingfound'] . '</p></div>';
+ }
+ }
+
+ /**
+ * Inserts the tag toolbar button
+ */
+ function insert_toolbar_button(Doku_Event $event, $param) {
+ $event->data[] = array(
+ 'type' => 'format',
+ 'title' => $this->getLang('toolbar_icon'),
+ 'icon' => '../../plugins/tag/images/tag-toolbar.png',
+ 'open' => '{{tag>',
+ 'close' => '}}'
+ );
+ }
+
+ /**
+ * Prevent displaying underscores instead of blanks inside the page keywords
+ */
+ function _handle_keywords(Doku_Event $event) {
+ global $ID;
+
+ // Fetch tags for the page; stop proceeding when no tags specified
+ $tags = p_get_metadata($ID, 'subject', METADATA_DONT_RENDER);
+ if(is_null($tags)) true;
+
+ // Replace underscores with blanks
+ foreach($event->data['meta'] as &$meta) {
+ if($meta['name'] == 'keywords') {
+ $meta['content'] = str_replace('_', ' ', $meta['content']);
+ }
+ }
+ }
+}
+
+// vim:ts=4:sw=4:et:
diff --git a/platform/www/lib/plugins/tag/conf/default.php b/platform/www/lib/plugins/tag/conf/default.php
new file mode 100644
index 0000000..9f0b314
--- /dev/null
+++ b/platform/www/lib/plugins/tag/conf/default.php
@@ -0,0 +1,13 @@
+<?php
+/**
+ * Options for the Tag Plugin
+ */
+$conf['namespace'] = 'tag'; // where should tag links point to? default: 'tag'
+$conf['sortkey'] = 'title'; // sort key for topic lists
+$conf['sortorder'] = 'ascending'; // ascending or descending
+$conf['pagelist_flags'] = 'list'; // formatting options for the page list plugin
+$conf['toolbar_icon'] = 0; // enables/disables the toolbar icon
+$conf['list_tags_of_subns'] = 0; // list also tags in subnamespaces of a specified namespace (count syntax)
+$conf['tags_list_css'] = 'tags'; // wich CSS style to use for tag list?
+
+//Setup VIM: ex: et ts=2 :
diff --git a/platform/www/lib/plugins/tag/conf/metadata.php b/platform/www/lib/plugins/tag/conf/metadata.php
new file mode 100644
index 0000000..8fd97c1
--- /dev/null
+++ b/platform/www/lib/plugins/tag/conf/metadata.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Metadata for configuration manager plugin
+ * Additions for the tag plugin
+ *
+ * @author Esther Brunner <wikidesign@gmail.com>
+ */
+
+$meta['namespace'] = array('string');
+$meta['sortkey'] = array('multichoice',
+ '_choices' => array('cdate', 'mdate', 'pagename', 'id', 'ns', 'title'));
+$meta['sortorder'] = array('multichoice',
+ '_choices' => array('ascending', 'descending'));
+$meta['pagelist_flags'] = array('string');
+$meta['toolbar_icon'] = array('onoff');
+$meta['list_tags_of_subns'] = array('onoff');
+$meta['tags_list_css'] = array('multichoice',
+ '_choices' => array('tags', 'tagstop'));
+
+//Setup VIM: ex: et ts=2 :
diff --git a/platform/www/lib/plugins/tag/helper.php b/platform/www/lib/plugins/tag/helper.php
new file mode 100644
index 0000000..666c5e2
--- /dev/null
+++ b/platform/www/lib/plugins/tag/helper.php
@@ -0,0 +1,513 @@
+<?php
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Esther Brunner <wikidesign@gmail.com>
+ */
+
+/**
+ * Helper part of the tag plugin, allows to query and print tags
+ */
+class helper_plugin_tag extends DokuWiki_Plugin {
+
+ var $namespace = ''; // namespace tag links point to
+
+ var $sort = ''; // sort key
+ var $topic_idx = array();
+
+ /**
+ * Constructor gets default preferences and language strings
+ */
+ function __construct() {
+ global $ID;
+
+ $this->namespace = $this->getConf('namespace');
+ if (!$this->namespace) $this->namespace = getNS($ID);
+ $this->sort = $this->getConf('sortkey');
+ }
+
+ /**
+ * Returns some documentation of the methods provided by this helper part
+ *
+ * @return array Method description
+ */
+ function getMethods() {
+ $result = array();
+ $result[] = array(
+ 'name' => 'th',
+ 'desc' => 'returns the header for the tags column for pagelist',
+ 'return' => array('header' => 'string'),
+ );
+ $result[] = array(
+ 'name' => 'td',
+ 'desc' => 'returns the tag links of a given page',
+ 'params' => array('id' => 'string'),
+ 'return' => array('links' => 'string'),
+ );
+ $result[] = array(
+ 'name' => 'tagLinks',
+ 'desc' => 'generates tag links for given words',
+ 'params' => array('tags' => 'array'),
+ 'return' => array('links' => 'string'),
+ );
+ $result[] = array(
+ 'name' => 'getTopic',
+ 'desc' => 'returns a list of pages tagged with the given keyword',
+ 'params' => array(
+ 'namespace (optional)' => 'string',
+ 'number (not used)' => 'integer',
+ 'tag (required)' => 'string'),
+ 'return' => array('pages' => 'array'),
+ );
+ $result[] = array(
+ 'name' => 'tagRefine',
+ 'desc' => 'refines an array of pages with tags',
+ 'params' => array(
+ 'pages to refine' => 'array',
+ 'refinement tags' => 'string'),
+ 'return' => array('pages' => 'array'),
+ );
+ $result[] = array(
+ 'name' => 'tagOccurrences',
+ 'desc' => 'returns a list of tags with their number of occurrences',
+ 'params' => array(
+ 'list of tags to get the occurrences for' => 'array',
+ 'namespaces to which the search shall be restricted' => 'array',
+ 'if all tags shall be returned (then the first parameter is ignored)' => 'boolean',
+ 'if the namespaces shall be searched recursively' => 'boolean'),
+ 'return' => array('tags' => 'array'),
+ );
+ return $result;
+ }
+
+ /**
+ * Returns the column header for th Pagelist Plugin
+ */
+ function th() {
+ return $this->getLang('tags');
+ }
+
+ /**
+ * Returns the cell data for the Pagelist Plugin
+ */
+ function td($id) {
+ $subject = $this->_getSubjectMetadata($id);
+ return $this->tagLinks($subject);
+ }
+
+ /**
+ * Returns the links for given tags
+ *
+ * @param array $tags an array of tags
+ * @return string HTML link tags
+ */
+ function tagLinks($tags) {
+ if (empty($tags) || ($tags[0] == '')) return '';
+
+ $links = array();
+ foreach ($tags as $tag) {
+ $links[] = $this->tagLink($tag);
+ }
+ return implode(','.DOKU_LF.DOKU_TAB, $links);
+ }
+
+ /**
+ * Returns the link for one given tag
+ *
+ * @param string $tag the tag the link shall point to
+ * @param string $title the title of the link (optional)
+ * @param bool $dynamic if the link class shall be changed if no pages with the specified tag exist
+ * @return string The HTML code of the link
+ */
+ function tagLink($tag, $title = '', $dynamic = false) {
+ global $conf;
+ $svtag = $tag;
+ $tag_title = str_replace('_', ' ', noNS($tag));
+ resolve_pageid($this->namespace, $tag, $exists); // resolve shortcuts
+ if ($exists) {
+ $class = 'wikilink1';
+ $url = wl($tag);
+ if ($conf['useheading']) {
+ // important: set sendond param to false to prevent recursion!
+ $heading = p_get_first_heading($tag, false);
+ if ($heading) $tag_title = $heading;
+ }
+ } else {
+ if ($dynamic) {
+ $pages = $this->getTopic('', 1, $svtag);
+ if (empty($pages)) {
+ $class = 'wikilink2';
+ } else {
+ $class = 'wikilink1';
+ }
+ } else {
+ $class = 'wikilink1';
+ }
+ $url = wl($tag, array('do'=>'showtag', 'tag'=>$svtag));
+ }
+ if (!$title) $title = $tag_title;
+ $link = array(
+ 'href' => $url,
+ 'class' => $class,
+ 'tooltip' => hsc($tag),
+ 'title' => hsc($title)
+ );
+ trigger_event('PLUGIN_TAG_LINK', $link);
+ $link = '<a href="'.$link['href'].'" class="'.$link['class'].'" title="'.$link['tooltip'].'" rel="tag">'.$link['title'].'</a>';
+ return $link;
+ }
+
+ /**
+ * Returns a list of pages with a certain tag; very similar to ft_backlinks()
+ *
+ * @param string $ns A namespace to which all pages need to belong, "." for only the root namespace
+ * @param int $num The maximum number of pages that shall be returned
+ * @param string $tag The tag that shall be searched
+ * @return array The list of pages
+ *
+ * @author Esther Brunner <wikidesign@gmail.com>
+ */
+ function getTopic($ns = '', $num = NULL, $tag = '') {
+ if (!$tag) $tag = $_REQUEST['tag'];
+ $tag = $this->_parseTagList($tag, true);
+ $result = array();
+
+ // find the pages using topic.idx
+ $pages = $this->_tagIndexLookup($tag);
+ if (!count($pages)) return $result;
+
+ foreach ($pages as $page) {
+ // exclude pages depending on ACL and namespace
+ if($this->_notVisible($page, $ns)) continue;
+ $tags = $this->_getSubjectMetadata($page);
+ // don't trust index
+ if (!$this->_checkPageTags($tags, $tag)) continue;
+
+ // get metadata
+ $meta = p_get_metadata($page);
+
+ $perm = auth_quickaclcheck($page);
+
+ // skip drafts unless for users with create privilege
+ $draft = ($meta['type'] == 'draft');
+ if ($draft && ($perm < AUTH_CREATE)) continue;
+
+ $title = $meta['title'];
+ $date = ($this->sort == 'mdate' ? $meta['date']['modified'] : $meta['date']['created'] );
+ $taglinks = $this->tagLinks($tags);
+
+ // determine the sort key
+ if ($this->sort == 'id') $key = $page;
+ elseif ($this->sort == 'ns') {
+ $pos = strrpos($page, ':');
+ if ($pos === false) $key = "\0".$page;
+ else $key = substr_replace($page, "\0\0", $pos, 1);
+ $key = str_replace(':', "\0", $key);
+ } elseif ($this->sort == 'pagename') $key = noNS($page);
+ elseif ($this->sort == 'title') {
+ $key = utf8_strtolower($title);
+ if (empty($key)) $key = str_replace('_', ' ', noNS($page));
+ } else $key = $date;
+ // make sure that the key is unique
+ $key = $this->_uniqueKey($key, $result);
+
+ $result[$key] = array(
+ 'id' => $page,
+ 'title' => $title,
+ 'date' => $date,
+ 'user' => $meta['creator'],
+ 'desc' => $meta['description']['abstract'],
+ 'cat' => $tags[0],
+ 'tags' => $taglinks,
+ 'perm' => $perm,
+ 'exists' => true,
+ 'draft' => $draft, );
+
+ if ($num && count($result) >= $num) break;
+ }
+
+ // finally sort by sort key
+ if ($this->getConf('sortorder') == 'ascending') ksort($result);
+ else krsort($result);
+
+ return $result;
+ }
+
+ /**
+ * Refine found pages with tags (+tag: AND, -tag: (AND) NOT)
+ *
+ * @param array $pages The pages that shall be filtered, each page needs to be an array with a key "id"
+ * @param string $refine The list of tags in the form "tag +tag2 -tag3". The tags will be cleaned.
+ * @return array The filtered list of pages
+ */
+ function tagRefine($pages, $refine) {
+ if (!is_array($pages)) return $pages; // wrong data type
+ $tags = $this->_parseTagList($refine, true);
+ $all_pages = $this->_tagIndexLookup($tags);
+
+ foreach ($pages as $key => $page) {
+ if (!in_array($page['id'], $all_pages)) unset($pages[$key]);
+ }
+
+ return $pages;
+ }
+
+ /**
+ * Get count of occurrences for a list of tags
+ *
+ * @param array $tags array of tags
+ * @param array $namespaces array of namespaces where to count the tags
+ * @param boolean $allTags boolean if all available tags should be counted
+ * @param boolean $recursive boolean if pages in subnamespaces are allowed
+ * @return array
+ */
+ function tagOccurrences($tags, $namespaces = NULL, $allTags = false, $recursive = NULL) {
+ // map with trim here in order to remove newlines from tags
+ if($allTags) $tags = array_map('trim', idx_getIndex('subject', '_w'));
+ $tags = $this->_cleanTagList($tags);
+ $otags = array(); //occurrences
+ if(!$namespaces || $namespaces[0] == '' || !is_array($namespaces)) $namespaces = NULL; // $namespaces not specified
+
+ $indexer = idx_get_indexer();
+ $indexer_pages = $indexer->lookupKey('subject', $tags, array($this, '_tagCompare'));
+
+ $root_allowed = ($namespaces == NULL ? false : in_array('.', $namespaces));
+ if ($recursive === NULL)
+ $recursive = $this->getConf('list_tags_of_subns');
+
+ foreach ($tags as $tag) {
+ if (!isset($indexer_pages[$tag])) continue;
+
+ // just to be sure remove duplicate pages from the list of pages
+ $pages = array_unique($indexer_pages[$tag]);
+
+ // don't count hidden pages or pages the user can't access
+ // for performance reasons this doesn't take drafts into account
+ $pages = array_filter($pages, array($this, '_isVisible'));
+
+ if (empty($pages)) continue;
+
+ if ($namespaces == NULL || ($root_allowed && $recursive)) {
+ // count all pages
+ $otags[$tag] = count($pages);
+ } else if (!$recursive) {
+ // filter by exact namespace
+ $otags[$tag] = 0;
+ foreach ($pages as $page) {
+ $ns = getNS($page);
+ if (($ns == false && $root_allowed) || in_array($ns, $namespaces)) $otags[$tag]++;
+ }
+ } else { // recursive, no root
+ $otags[$tag] = 0;
+ foreach ($pages as $page) {
+ foreach ($namespaces as $ns) {
+ if(strpos($page, $ns.':') === 0 ) {
+ $otags[$tag]++ ;
+ break;
+ }
+ }
+ }
+ }
+ // don't return tags without pages
+ if ($otags[$tag] == 0) unset($otags[$tag]);
+ }
+ return $otags;
+ }
+
+ /**
+ * Get the subject metadata cleaning the result
+ *
+ * @param string $id the page id
+ * @return array
+ */
+ function _getSubjectMetadata($id){
+ $tags = p_get_metadata($id, 'subject');
+ if (!is_array($tags)) $tags = explode(' ', $tags);
+ return array_unique($tags);
+ }
+
+ /**
+ * Tag index lookup
+ *
+ * @param array $tags the tags to filter
+ * @return array the matching page ids
+ */
+ function _tagIndexLookup($tags) {
+ $result = array(); // array of page ids
+
+ $clean_tags = array();
+ foreach ($tags as $i => $tag) {
+ if (($tag[0] == '+') || ($tag[0] == '-'))
+ $clean_tags[$i] = substr($tag, 1);
+ else
+ $clean_tags[$i] = $tag;
+ }
+
+ $indexer = idx_get_indexer();
+ $pages = $indexer->lookupKey('subject', $clean_tags, array($this, '_tagCompare'));
+ // use all pages as basis if the first tag isn't an "or"-tag or if there are no tags given
+ if (empty($tags) || $clean_tags[0] != $tags[0]) $result = $indexer->getPages();
+
+ foreach ($tags as $i => $tag) {
+ $t = $clean_tags[$i];
+ if (!is_array($pages[$t])) $pages[$t] = array();
+
+ if ($tag[0] == '+') { // AND: add only if in both arrays
+ $result = array_intersect($result, $pages[$t]);
+ } elseif ($tag[0] == '-') { // NOT: remove array from docs
+ $result = array_diff($result, $pages[$t]);
+ } else { // OR: add array to docs
+ $result = array_unique(array_merge($result, $pages[$t]));
+ }
+ }
+
+ return $result;
+ }
+
+
+ /**
+ * Splits a string into an array of tags
+ */
+ function _parseTagList($tags, $clean = false) {
+
+ // support for "quoted phrase tags"
+ if (preg_match_all('#".*?"#', $tags, $matches)) {
+ foreach ($matches[0] as $match) {
+ $replace = str_replace(' ', '_', substr($match, 1, -1));
+ $tags = str_replace($match, $replace, $tags);
+ }
+ }
+
+ $tags = preg_split('/ /', $tags, -1, PREG_SPLIT_NO_EMPTY);
+
+ if ($clean) {
+ return $this->_cleanTagList($tags);
+ } else {
+ return $tags;
+ }
+ }
+
+ /**
+ * Clean a list (array) of tags using _cleanTag
+ */
+ function _cleanTagList($tags) {
+ return array_unique(array_map(array($this, '_cleanTag'), $tags));
+ }
+
+ /**
+ * Cleans a tag using cleanID while preserving a possible prefix of + or -
+ */
+ function _cleanTag($tag) {
+ $prefix = substr($tag, 0, 1);
+ $tag = $this->_applyMacro($tag);
+ if ($prefix === '-' || $prefix === '+') {
+ return $prefix.cleanID($tag);
+ } else {
+ return cleanID($tag);
+ }
+ }
+
+ /**
+ * Makes user or date dependent topic lists possible
+ */
+ function _applyMacro($id) {
+ /** @var DokuWiki_Auth_Plugin $auth */
+ global $INFO, $auth;
+
+ $user = $_SERVER['REMOTE_USER'];
+ $group = '';
+ // .htaccess auth doesn't provide the auth object
+ if($auth) {
+ $userdata = $auth->getUserData($user);
+ $group = $userdata['grps'][0];
+ }
+
+ $replace = array(
+ '@USER@' => cleanID($user),
+ '@NAME@' => cleanID($INFO['userinfo']['name']),
+ '@GROUP@' => cleanID($group),
+ '@YEAR@' => date('Y'),
+ '@MONTH@' => date('m'),
+ '@DAY@' => date('d'),
+ );
+ return str_replace(array_keys($replace), array_values($replace), $id);
+ }
+
+ /**
+ * Non-recursive function to check whether an array key is unique
+ *
+ * @author Esther Brunner <wikidesign@gmail.com>
+ * @author Ilya S. Lebedev <ilya@lebedev.net>
+ */
+ function _uniqueKey($key, &$result) {
+
+ // increase numeric keys by one
+ if (is_numeric($key)) {
+ while (array_key_exists($key, $result)) $key++;
+ return $key;
+
+ // append a number to literal keys
+ } else {
+ $num = 0;
+ $testkey = $key;
+ while (array_key_exists($testkey, $result)) {
+ $testkey = $key.$num;
+ $num++;
+ }
+ return $testkey;
+ }
+ }
+
+ /**
+ * Opposite of _notVisible
+ */
+ function _isVisible($id, $ns='') {
+ return !$this->_notVisible($id, $ns);
+ }
+ /**
+ * Check visibility of the page
+ *
+ * @param string $id the page id
+ * @param string $ns the namespace authorized
+ * @return bool if the page is hidden
+ */
+ function _notVisible($id, $ns="") {
+ if (isHiddenPage($id)) return true; // discard hidden pages
+ // discard if user can't read
+ if (auth_quickaclcheck($id) < AUTH_READ) return true;
+ // filter by namespace, root namespace is identified with a dot
+ if($ns == '.') {
+ // root namespace is specified, discard all pages who lay outside the root namespace
+ if(getNS($id) != false) return true;
+ } else {
+ // ("!==0" namespace found at position 0)
+ if ($ns && (strpos(':'.getNS($id).':', ':'.$ns.':') !== 0)) return true;
+ }
+ return !page_exists($id, '', false);
+ }
+
+ /**
+ * Helper function for the indexer in order to avoid interpreting wildcards
+ */
+ function _tagCompare($tag1, $tag2) {
+ return $tag1 === $tag2;
+ }
+
+ /**
+ * Check if the page is a real candidate for the result of the getTopic
+ *
+ * @param array $pagetags tags on the metadata of the page
+ * @param array $tags tags we are looking
+ * @return bool
+ */
+ function _checkPageTags($pagetags, $tags) {
+ $result = false;
+ foreach($tags as $tag) {
+ if ($tag[0] == "+" and !in_array(substr($tag, 1), $pagetags)) $result = false;
+ if ($tag[0] == "-" and in_array(substr($tag, 1), $pagetags)) $result = false;
+ if (in_array($tag, $pagetags)) $result = true;
+ }
+ return $result;
+ }
+
+}
+// vim:ts=4:sw=4:et:
diff --git a/platform/www/lib/plugins/tag/images/tag-toolbar.png b/platform/www/lib/plugins/tag/images/tag-toolbar.png
new file mode 100644
index 0000000..4b274d2
--- /dev/null
+++ b/platform/www/lib/plugins/tag/images/tag-toolbar.png
Binary files differ
diff --git a/platform/www/lib/plugins/tag/images/tag.gif b/platform/www/lib/plugins/tag/images/tag.gif
new file mode 100644
index 0000000..ac445bf
--- /dev/null
+++ b/platform/www/lib/plugins/tag/images/tag.gif
Binary files differ
diff --git a/platform/www/lib/plugins/tag/lang/ar/lang.php b/platform/www/lib/plugins/tag/lang/ar/lang.php
new file mode 100644
index 0000000..d755e37
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/ar/lang.php
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Muhammad Bashir Al-Noimi <bashir.storm@gmail.com>
+ * @author alhajr <alhajr300@gmail.com>
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['tag'] = 'العلامة';
+$lang['tags'] = 'العلامات';
+$lang['topic'] = 'الموضوع';
+$lang['count'] = 'العد';
+$lang['toolbar_icon'] = 'إدراج علامة-بناء الجملة';
+$lang['empty_output'] = 'الإخراج فارغة';
+
+$lang['include'] = 'تضمين';
+$lang['exclude'] = 'استبعاد';
+$lang['use_and'] = 'استخدام منطق AND';
+$lang['no_tags'] = 'لم يتم العثور على العلامات ';
diff --git a/platform/www/lib/plugins/tag/lang/ar/settings.php b/platform/www/lib/plugins/tag/lang/ar/settings.php
new file mode 100644
index 0000000..3573cd0
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/ar/settings.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Muhammad Bashir Al-Noimi <bashir.storm@gmail.com>
+ * @author alhajr <alhajr300@gmail.com>
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['namespace'] = 'فضاء الأسماء الإفتراضي للأقسام';
+$lang['toolbar_icon'] = 'تظهر أيقونة شريط الأدوات (مسح ذاكرة التخزين المؤقت للبيانات//* وذاكرة التخزين المؤقت للمستعرض إذا لم يتم عرض)';
+
+$lang['sortkey'] = 'ترتيب التدوينات حسب:';
+$lang['sortkey_o_cdate'] = 'تاريخ الإنشاء';
+$lang['sortkey_o_mdate'] = 'تاريخ التعديل';
+$lang['sortkey_o_pagename'] = 'إسم الصفحة';
+$lang['sortkey_o_id'] = 'رقم الصفحة';
+$lang['sortkey_o_ns'] = 'نيم سبيس (مساحة الاسم)';
+$lang['sortkey_o_title'] = 'العنوان';
+
+$lang['sortorder'] = 'ترتيب الفرز';
+$lang['sortorder_o_ascending'] = 'ترتيب تصاعدي';
+$lang['sortorder_o_descending'] = 'تنازلي';
+
+$lang['pagelist_flags'] = 'تنسيق إعلام ل taglist (مفصولة بفاصلة، لإعلام المتوفرة راجع وثائق البرنامج المساعد pagelist )';
+
+$lang['list_tags_of_subns'] = 'قائمة أيضا العلامات في مساحات الأسماء الفرعية لمساحة الاسم المحدد (بناء الجملة عدد مرات)';
+
+$lang['tags_list_css'] = 'اختر النمط المطبق على قائمة علامات الصفحات';
+$lang['tags_list_css_o_tags'] = 'أسلوب إفتراضي';
+$lang['tags_list_css_o_tagstop'] = 'الأمثل لقائمة العلامات في أعلى الصفحة';
diff --git a/platform/www/lib/plugins/tag/lang/be/lang.php b/platform/www/lib/plugins/tag/lang/be/lang.php
new file mode 100644
index 0000000..cf61c9e
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/be/lang.php
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['tag'] = 'Тэг';
+$lang['tags'] = 'Тэгі';
+$lang['topic'] = 'Тэмы';
+$lang['count'] = 'Колькасць';
+$lang['toolbar_icon'] = 'Уставіць тэг-сінтаксіс';
+$lang['empty_output'] = 'Пусты вывад';
+
+$lang['include'] = 'Включаць';
+$lang['exclude'] = 'Выключаць';
+$lang['use_and'] = 'Выкарыстоўваць лагічнае AND';
+$lang['no_tags'] = 'Тэгі не знойдзены';
diff --git a/platform/www/lib/plugins/tag/lang/be/settings.php b/platform/www/lib/plugins/tag/lang/be/settings.php
new file mode 100644
index 0000000..4e236dc
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/be/settings.php
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['namespace'] = 'Прастора імёнаў па змаўчанні для тэгаў';
+$lang['toolbar_icon'] = 'Паказваць кнопку на панэлі інструментаў (калі значок не адлюстроўваецца, ачысціце data/cache/* і кэш браўзэра)';
+
+$lang['sortkey'] = 'Сартаваць спіс старонак па:';
+$lang['sortkey_o_cdate'] = 'даце стварэння';
+$lang['sortkey_o_mdate'] = 'даце рэдагавання';
+$lang['sortkey_o_pagename'] = 'імя старонкі';
+$lang['sortkey_o_id'] = 'ID старонкі';
+$lang['sortkey_o_ns'] = 'прасторы назваў';
+$lang['sortkey_o_title'] = 'загалоўку';
+
+$lang['sortorder'] = 'Парадак сартавання';
+$lang['sortorder_o_ascending'] = 'па ўзрастанні';
+$lang['sortorder_o_descending'] = 'па змяншэнні';
+
+$lang['pagelist_flags'] = 'Прыкметы (flags) фарматавання для спісу тэгаў (коскамі; спіс даступных прыкмет (flags) апісаны ў дакументацыі плагіна Pagelist)';
+
+$lang['list_tags_of_subns'] = 'Таксама паказваць тэгі ў подпространство імёнаў адзначаных прастор імёнаў (сінтаксіс падліку (count))';
+
+$lang['tags_list_css'] = 'Вылучыць стыль для спісу тэгаў на старонках';
+$lang['tags_list_css_o_tags'] = 'стыль па змаўчанні';
+$lang['tags_list_css_o_tagstop'] = 'аптымізацыя для размяшчэння наверсе старонкі';
diff --git a/platform/www/lib/plugins/tag/lang/bg/lang.php b/platform/www/lib/plugins/tag/lang/bg/lang.php
new file mode 100644
index 0000000..89f5be1
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/bg/lang.php
@@ -0,0 +1,19 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Kiril <neohidra@gmail.com>
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['tag'] = 'Етикет';
+$lang['tags'] = 'Етикети';
+$lang['topic'] = 'Тема';
+$lang['count'] = 'Брой';
+$lang['toolbar_icon'] = 'Вмъкване на синтаксис за етикет';
+$lang['empty_output'] = 'Празен изход';
+
+$lang['include'] = 'Включи';
+$lang['exclude'] = 'Изключи';
+$lang['use_and'] = 'Ползван логика AND';
+$lang['no_tags'] = 'Не са открити етикети';
diff --git a/platform/www/lib/plugins/tag/lang/bg/settings.php b/platform/www/lib/plugins/tag/lang/bg/settings.php
new file mode 100644
index 0000000..aba7eb8
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/bg/settings.php
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Kiril <neohidra@gmail.com>
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['namespace'] = 'Стандартно именно пространство за етикетите';
+$lang['toolbar_icon'] = 'Показване на икона в лентата с инструменти (ако не виждате бутона изчистете съдържанието на data/cache/* и кеша на браузера ';
+
+$lang['sortkey'] = 'Сортиране на списъците с теми по';
+$lang['sortkey_o_cdate'] = 'дата на създаване';
+$lang['sortkey_o_mdate'] = 'дата на редактиране';
+$lang['sortkey_o_pagename'] = 'име на страница';
+$lang['sortkey_o_id'] = 'ID на страница';
+$lang['sortkey_o_ns'] = 'именно пространство';
+$lang['sortkey_o_title'] = 'заглавие';
+
+$lang['sortorder'] = 'Сортиране';
+$lang['sortorder_o_ascending'] = 'възходящо';
+$lang['sortorder_o_descending'] = 'низходящо';
+
+$lang['pagelist_flags'] = 'Форматиране на флагове за списъка с тагове (разделени със запетая, за наличните флагове вижте документацията на приставката Pagelist)';
+
+$lang['list_tags_of_subns'] = 'Показване и на етикети от подименните пространства (count syntax)';
+
+$lang['tags_list_css'] = 'Изберете стил, който да се прилага към списъка с етикети на страниците';
+$lang['tags_list_css_o_tags'] = 'стандартния';
+$lang['tags_list_css_o_tagstop'] = 'оптимален за списък от етикети над страницата';
diff --git a/platform/www/lib/plugins/tag/lang/ckb/lang.php b/platform/www/lib/plugins/tag/lang/ckb/lang.php
new file mode 100644
index 0000000..0b7f022
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/ckb/lang.php
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author qezwan <qezwan@gmail.com>
+ */
+
+$lang['tag'] = 'تاگ';
+$lang['tags'] = 'تاگەکان';
+$lang['topic'] = 'بابەت';
+$lang['count'] = '#';
+$lang['toolbar_icon'] = 'دانانی تاگ-ڕستە';
+$lang['empty_output'] = 'دەرچوی بەتاڵ';
+
+$lang['include'] = 'لەخۆدەگرێت';
+$lang['exclude'] = 'دەرکردن';
+$lang['use_and'] = 'بەکارهێنان و';
+$lang['no_tags'] = 'هیچ تاگێک نەدۆزرایەوە';
diff --git a/platform/www/lib/plugins/tag/lang/ckb/settings.php b/platform/www/lib/plugins/tag/lang/ckb/settings.php
new file mode 100644
index 0000000..95c7985
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/ckb/settings.php
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author qezwan <qezwan@gmail.com>
+ */
+
+$lang['namespace'] = 'بۆشایی ناوی ئاسایی بۆ تاگەکان';
+$lang['toolbar_icon'] = 'پیشاندانی وێنۆکی شریتی ئامڕاز (زانیاری/حەشارگە/* و حەشارگەی وێبگەڕ ئەگەر پیشان نەدرا)';
+
+$lang['sortkey'] = 'پۆلێنکردنی لیستەکانی بابەت بەپێی';
+$lang['sortkey_o_cdate'] = 'بەرواری دروست کردن';
+$lang['sortkey_o_mdate'] = 'دەستکاری بەروار';
+$lang['sortkey_o_pagename'] = 'ناوی پەڕە';
+$lang['sortkey_o_id'] = 'ناسنامەی پەڕە';
+$lang['sortkey_o_ns'] = 'بۆشایی ناو';
+$lang['sortkey_o_title'] = 'ناونیشان';
+
+$lang['sortorder'] = 'ڕیزکردن لە ریزبەند';
+$lang['sortorder_o_ascending'] = 'بەرەو سەرەوە';
+$lang['sortorder_o_descending'] = 'بەرەو خوار';
+
+$lang['pagelist_flags'] = 'فۆرماتکردنی ئاڵاکان بۆ لیستی تاگ (کۆما-جیاکراوە, بۆ ئاڵای بەردەست ببینە دۆکیومێنتەکان لە پیتەلیست پێوەکراو)';
+
+$lang['list_tags_of_subns'] = 'هەروەها پێرستی تاگەکان لە ژێربۆشایی ناوەکانی بۆشایی ناوێکی تایبەت دیاریکراو (ڕستەسازی ژماردن)';
+
+$lang['tags_list_css'] = 'هەڵبژاردنی شێوازی کارپێکراو بۆ لیستی تاگی لاپەڕەکان';
+$lang['tags_list_css_o_tags'] = 'شێوازی بنەڕەت';
+$lang['tags_list_css_o_tagstop'] = 'باشترکراوە بۆ لیستی تاگەکان لە سەرەوەی لاپەڕەکە';
diff --git a/platform/www/lib/plugins/tag/lang/cs/lang.php b/platform/www/lib/plugins/tag/lang/cs/lang.php
new file mode 100644
index 0000000..7aa7353
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/cs/lang.php
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * Czech language file (UTF-8 encoding)
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Lukas Zapletal <lukas.zapletal@gmail.com>
+ * @author Robert Surý <rsurycz@seznam.cz>
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['tag'] = 'Tag';
+$lang['tags'] = 'Tagy';
+$lang['topic'] = 'Téma';
+$lang['count'] = 'Počet';
+$lang['toolbar_icon'] = 'Vlož Tag-Syntax';
+$lang['empty_output'] = 'Prázdný výstup';
+
+$lang['include'] = 'Include';
+$lang['exclude'] = 'Exclude';
+$lang['use_and'] = 'Použít logické AND';
+$lang['no_tags'] = 'Nenalezeny žádné tagy';
diff --git a/platform/www/lib/plugins/tag/lang/cs/settings.php b/platform/www/lib/plugins/tag/lang/cs/settings.php
new file mode 100644
index 0000000..4edc9a7
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/cs/settings.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * Czech language file (UTF-8 encoding)
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Lukas Zapletal <lukas.zapletal at gmail dot com>
+ */
+
+$lang['namespace'] = 'Výchozí jmenný prostor pro tagy';
+$lang['toolbar_icon'] = 'Zobrazit toolbar ikonku (pokud se nezobrazuje, smažte data/cache/* a cache prohlížeče)';
+
+$lang['sortkey'] = 'razení zápisků podle';
+$lang['sortkey_o_cdate'] = 'data vytvoření';
+$lang['sortkey_o_mdate'] = 'data modifikace';
+$lang['sortkey_o_pagename'] = 'názvu stránky';
+$lang['sortkey_o_id'] = 'ID stránky';
+$lang['sortkey_o_ns'] = 'jmenný prostor';
+$lang['sortkey_o_title'] = 'nadpis';
+
+$lang['sortorder'] = 'pořadí';
+$lang['sortorder_o_ascending'] = 'vzestupné';
+$lang['sortorder_o_descending'] = 'sestupné';
+
+$lang['pagelist_flags'] = 'Formátovací flags pro list tagů (comma-separated, viz dostupné flags v dokumentaci pluginu pagelist)';
+
+$lang['list_tags_of_subns'] = 'List také tags in podjmenných prostorů daného jmenného prostoru';
+
+$lang['tags_list_css'] = 'Vyber styl aplikovaný na stránku seznam tagů ';
+$lang['tags_list_css_o_tags'] = 'výchozí styl';
+$lang['tags_list_css_o_tagstop'] = 'optimalizováno pro zobrazení seznamu tagů v horní části stránky';
diff --git a/platform/www/lib/plugins/tag/lang/cy/lang.php b/platform/www/lib/plugins/tag/lang/cy/lang.php
new file mode 100644
index 0000000..bf8587d
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/cy/lang.php
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Alan Davies <ben.brynsadler@gmail.com>
+ * @author diafol <ben.brynsadler@gmail.com>
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['tag'] = 'Tag';
+$lang['tags'] = 'Tagiau';
+$lang['topic'] = 'Testun';
+$lang['count'] = 'Meintiau';
+$lang['toolbar_icon'] = 'Mewnosod Cystrawen-Tag';
+$lang['empty_output'] = 'Allbwn Gwag';
+
+$lang['include'] = 'Cynnwys';
+$lang['exclude'] = 'Eithrio';
+$lang['use_and'] = 'Defnyddiwch resymeg AND';
+$lang['no_tags'] = 'Dim tagiau wedi\'u darganfod';
diff --git a/platform/www/lib/plugins/tag/lang/cy/settings.php b/platform/www/lib/plugins/tag/lang/cy/settings.php
new file mode 100644
index 0000000..a9b2640
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/cy/settings.php
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Alan Davies <ben.brynsadler@gmail.com>
+ */
+
+$lang['namespace'] = 'Namespace diofyn ar gyfer tagiau';
+$lang['toolbar_icon'] = 'Dangos eicon y bar offer (cliriwch data/cache/* a storfa eich porwr os \'dyw e ddim yn ymddangos)';
+
+$lang['sortkey'] = 'trefnu rhestr testunau gan';
+$lang['sortkey_o_cdate'] = 'dyddiad creu';
+$lang['sortkey_o_mdate'] = 'dyddiad newid';
+$lang['sortkey_o_pagename'] = 'enw\'r dudalen';
+$lang['sortkey_o_id'] = 'ID tudalen';
+$lang['sortkey_o_ns'] = 'namespace';
+$lang['sortkey_o_title'] = 'teitl';
+
+$lang['sortorder'] = 'trefn';
+$lang['sortorder_o_ascending'] = 'esgyn';
+$lang['sortorder_o_descending'] = 'disgyn';
+
+$lang['pagelist_flags'] = 'Fflagiau fformatio ar gyfer y rhestr tagiau (gwahanu gan goma; ar gyfer fflagiau posib, gwelwch ddogfennaeth yr ategyn \'Pagelist\')';
+
+$lang['list_tags_of_subns'] = 'Rhestrwch dagiau hefyd yn y subnamespaces o\'r namespace penodol (cystrawen cyfri) ';
+
+$lang['tags_list_css'] = 'Dewis arddull i osod ar restr dagiau tudalennau';
+$lang['tags_list_css_o_tags'] = 'arddull ddiofyn';
+$lang['tags_list_css_o_tagstop'] = 'optimeiddiwyd am restr dagiau ar ben y dudalen';
diff --git a/platform/www/lib/plugins/tag/lang/da/lang.php b/platform/www/lib/plugins/tag/lang/da/lang.php
new file mode 100644
index 0000000..add2cb3
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/da/lang.php
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Søren Birk <soer9648@eucl.dk>
+ * @author Jacob Palm <jacobpalmdk@icloud.com>
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['tag'] = 'Tag';
+$lang['tags'] = 'Tags';
+$lang['topic'] = 'Emne';
+$lang['count'] = 'Mængde';
+$lang['toolbar_icon'] = 'Indsæt Tag-Syntaks';
+$lang['empty_output'] = 'Tomt Output';
+
+$lang['include'] = 'Inkludér';
+$lang['exclude'] = 'Ekskludér';
+$lang['use_and'] = 'Brug logik AND';
+$lang['no_tags'] = 'Ingen tags fundet';
diff --git a/platform/www/lib/plugins/tag/lang/da/settings.php b/platform/www/lib/plugins/tag/lang/da/settings.php
new file mode 100644
index 0000000..05f475d
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/da/settings.php
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Søren Birk <soer9648@eucl.dk>
+ * @author Jacob Palm <jacobpalmdk@icloud.com>
+ */
+
+$lang['namespace'] = 'Standard navnerum for tags';
+$lang['toolbar_icon'] = 'Vis ikon for værktøjslinje (ryd data/cache/* og browser-cache, hvis den ikke vises)';
+
+$lang['sortkey'] = 'sortér emneliste efter';
+$lang['sortkey_o_cdate'] = 'oprettelsesdato';
+$lang['sortkey_o_mdate'] = 'redigeringsdato';
+$lang['sortkey_o_pagename'] = 'sidenavn';
+$lang['sortkey_o_id'] = 'side-ID';
+$lang['sortkey_o_ns'] = 'navnerum';
+$lang['sortkey_o_title'] = 'titel';
+
+$lang['sortorder'] = 'sorteringsorden';
+$lang['sortorder_o_ascending'] = 'stigende';
+$lang['sortorder_o_descending'] = 'faldende';
+
+$lang['pagelist_flags'] = 'Formateringsflag for tag-listen (kommasepareret - se dokumentationen for pagelist plugin, for tilgængelige flag)';
+
+$lang['list_tags_of_subns'] = 'List også tags i under-navnerum for et specificeret navnerum (tæl syntaks)';
+
+$lang['tags_list_css'] = 'Vælg stil der skal anvendes til tag-listen på sider';
+$lang['tags_list_css_o_tags'] = 'standard stil';
+$lang['tags_list_css_o_tagstop'] = 'optimeret til visning af tag-liste øverst på side';
diff --git a/platform/www/lib/plugins/tag/lang/de-informal/lang.php b/platform/www/lib/plugins/tag/lang/de-informal/lang.php
new file mode 100644
index 0000000..eac3886
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/de-informal/lang.php
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Sebastian Klemm <sebastian_klemm@freenet.de>
+ * @author rnck <dokuwiki@rnck.de>
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['tag'] = 'Tag';
+$lang['tags'] = 'Tags';
+$lang['topic'] = 'Thema';
+$lang['count'] = 'Menge';
+$lang['toolbar_icon'] = 'Tag-Syntax einfügen';
+$lang['empty_output'] = 'Leere Ausgabe';
+
+$lang['include'] = 'Einschließen';
+$lang['exclude'] = 'Ausschließen';
+$lang['use_and'] = 'Logisches AND verwenden';
+$lang['no_tags'] = 'Keine Tags gefunden';
diff --git a/platform/www/lib/plugins/tag/lang/de-informal/settings.php b/platform/www/lib/plugins/tag/lang/de-informal/settings.php
new file mode 100644
index 0000000..7b91485
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/de-informal/settings.php
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Sebastian Klemm <sebastian_klemm@freenet.de>
+ * @author rnck <dokuwiki@rnck.de>
+ */
+
+$lang['namespace'] = 'Standard-Namensraum für Tags';
+$lang['toolbar_icon'] = 'Toolbar-Symbol anzeigen (data/cache/* und den Browser-Cache löschen, wenn das Symbol nicht angezeigt wird)';
+
+$lang['sortkey'] = 'Themenlisten sortieren nach:';
+$lang['sortkey_o_cdate'] = 'Erstellungsdatum';
+$lang['sortkey_o_mdate'] = 'Änderungsdatum';
+$lang['sortkey_o_pagename'] = 'Seitenname';
+$lang['sortkey_o_id'] = 'Seiten-ID';
+$lang['sortkey_o_ns'] = 'Namensraum';
+$lang['sortkey_o_title'] = 'Titel';
+
+$lang['sortorder'] = 'Sortierrichtung';
+$lang['sortorder_o_ascending'] = 'aufsteigend';
+$lang['sortorder_o_descending'] = 'absteigend';
+
+$lang['pagelist_flags'] = 'Formatieroptionen für die Tagliste (kommasepariert, für eine Liste der verfügbaren Optionen siehe die Dokumentation des Pagelist Plugins)';
+
+$lang['list_tags_of_subns'] = 'Tags anzeigen, die in Subnamespaces von angegebeben Namespaces liegen (count syntax)';
+
+$lang['tags_list_css'] = 'Wähle ein Aussehen für die Tag-Liste auf der Seite';
+$lang['tags_list_css_o_tags'] = 'Standardaussehen';
+$lang['tags_list_css_o_tagstop'] = 'Optimierte Tag-Liste für Seitenkopf';
diff --git a/platform/www/lib/plugins/tag/lang/de/lang.php b/platform/www/lib/plugins/tag/lang/de/lang.php
new file mode 100644
index 0000000..284e013
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/de/lang.php
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Esther Brunner <wikidesign@gmail.com>
+ * @author Dominik Eckelmann <deckelmann@gmail.com>
+ * @author Dennis Plöger <develop@dieploegers.de>
+ * @author Dana <dannax3@gmx.de>
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['tag'] = 'Tag';
+$lang['tags'] = 'Tags';
+$lang['topic'] = 'Thema';
+$lang['count'] = 'Menge';
+$lang['toolbar_icon'] = 'Tag-Syntax einfügen';
+$lang['empty_output'] = 'Leere Ausgabe';
+
+$lang['include'] = 'Einschließen';
+$lang['exclude'] = 'Ausschließen';
+$lang['use_and'] = 'Logisches AND verwenden';
+$lang['no_tags'] = 'Keine Tags gefunden';
diff --git a/platform/www/lib/plugins/tag/lang/de/settings.php b/platform/www/lib/plugins/tag/lang/de/settings.php
new file mode 100644
index 0000000..8b5b079
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/de/settings.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Esther Brunner <wikidesign@gmail.com>
+ * @author Padhie <develop@padhie.de>
+ * @author rnck <dokuwiki@rnck.de>
+ */
+
+$lang['namespace'] = 'Standard-Namensraum für Tags';
+$lang['toolbar_icon'] = 'Toolbar-Symbol anzeigen (data/cache/* und den Browser-Cache löschen, wenn das Symbol nicht angezeigt wird)';
+
+$lang['sortkey'] = 'Themenlisten sortieren nach:';
+$lang['sortkey_o_cdate'] = 'Erstellungsdatum';
+$lang['sortkey_o_mdate'] = 'Änderungsdatum';
+$lang['sortkey_o_pagename'] = 'Seitenname';
+$lang['sortkey_o_id'] = 'Seiten-ID';
+$lang['sortkey_o_ns'] = 'Namensraum';
+$lang['sortkey_o_title'] = 'Titel';
+
+$lang['sortorder'] = 'Sortierrichtung';
+$lang['sortorder_o_ascending'] = 'aufsteigend';
+$lang['sortorder_o_descending'] = 'absteigend';
+
+$lang['pagelist_flags'] = 'Formatieroptionen für die Tagliste (kommasepariert, für eine Liste der verfügbaren Optionen siehe die Dokumentation des Pagelist Plugins)';
+
+$lang['list_tags_of_subns'] = 'Tags anzeigen, die in Subnamespaces von angegebeben Namespaces liegen (count syntax)';
+
+$lang['tags_list_css'] = 'Wähle ein Aussehen für die Tag-Liste auf der Seite';
+$lang['tags_list_css_o_tags'] = 'Standardaussehen';
+$lang['tags_list_css_o_tagstop'] = 'Optimierte Tag-Liste für Seitenkopf';
diff --git a/platform/www/lib/plugins/tag/lang/el/lang.php b/platform/www/lib/plugins/tag/lang/el/lang.php
new file mode 100644
index 0000000..8a9637a
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/el/lang.php
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['tag'] = 'Ετικέτα';
+$lang['tags'] = 'Ετικέτες';
+$lang['topic'] = 'Θέμα';
+$lang['count'] = 'Ποσότητα';
+$lang['toolbar_icon'] = 'Εισαγωγή ετικέτας-σύνταξης';
+$lang['empty_output'] = 'Άδεια εξόδου';
+
+$lang['include'] = 'Συμπερίληψη';
+$lang['exclude'] = 'Εξαίρεση';
+$lang['use_and'] = 'Χρήση λογικής AND';
+$lang['no_tags'] = 'Δεν βρέθηκαν ετικέτες';
diff --git a/platform/www/lib/plugins/tag/lang/el/settings.php b/platform/www/lib/plugins/tag/lang/el/settings.php
new file mode 100644
index 0000000..90103f1
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/el/settings.php
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['namespace'] = 'Προεπιλεγμένος χώρος ονομάτων για ετικέτες';
+$lang['toolbar_icon'] = 'Εμφάνιση εικονιδίου γραμμής εργαλείων (εκκαθάριση "data/cache/*" και προσωρινή μνήμη του προγράμματος περιήγησης εάν δεν εμφανίζεται)';
+
+$lang['sortkey'] = 'ταξινόμηση λιστών θεμάτων κατά';
+$lang['sortkey_o_cdate'] = 'ημερομηνία δημιουργίας';
+$lang['sortkey_o_mdate'] = 'ημερομηνία τροποποίησης';
+$lang['sortkey_o_pagename'] = 'όνομα σελίδας';
+$lang['sortkey_o_id'] = 'αναγνωριστικό σελίδας';
+$lang['sortkey_o_ns'] = 'namespace';
+$lang['sortkey_o_title'] = 'τίτλος';
+
+$lang['sortorder'] = 'ταξινόμηση ταξινόμησης';
+$lang['sortorder_o_ascending'] = 'αύξουσα';
+$lang['sortorder_o_descending'] = 'φθίνουσα';
+
+$lang['pagelist_flags'] = 'Μορφοποίηση σημαιών για τη λίστα ετικετών (διαχωρισμένα με κόμμα, για τις διαθέσιμες σημαίες δείτε την τεκμηρίωση της προσθήκης Pagelist)';
+
+$lang['list_tags_of_subns'] = 'Λίστα επίσης ετικετών σε δευτερεύοντες χώρους ενός καθορισμένου χώρου ονομάτων (σύνταξη μέτρησης)';
+
+$lang['tags_list_css'] = 'Επιλέξτε στυλ που εφαρμόζεται στη σελίδα\' λίστα ετικετών';
+$lang['tags_list_css_o_tags'] = 'προεπιλεγμένο στυλ';
+$lang['tags_list_css_o_tagstop'] = 'βελτιστοποιημένη για λίστα ετικετών στο επάνω μέρος της σελίδας';
diff --git a/platform/www/lib/plugins/tag/lang/en/lang.php b/platform/www/lib/plugins/tag/lang/en/lang.php
new file mode 100644
index 0000000..1764d5b
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/en/lang.php
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * English language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Esther Brunner <wikidesign@gmail.com>
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+// custom language strings for the plugin
+$lang['tag'] = 'Tag';
+$lang['tags'] = 'Tags';
+$lang['topic'] = 'Topic';
+$lang['count'] = 'Quantity';
+$lang['toolbar_icon'] = 'Insert Tag-Syntax';
+$lang['empty_output'] = 'Empty Output';
+
+// search form of tagsearch syntax
+$lang['include'] = 'Include';
+$lang['exclude'] = 'Exclude';
+$lang['use_and'] = 'Use logic AND';
+$lang['no_tags'] = 'No tags found';
diff --git a/platform/www/lib/plugins/tag/lang/en/settings.php b/platform/www/lib/plugins/tag/lang/en/settings.php
new file mode 100644
index 0000000..e7d22f2
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/en/settings.php
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * English language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Esther Brunner <wikidesign@gmail.com>
+ */
+
+// for the configuration manager
+$lang['namespace'] = 'Default namespace for tags';
+$lang['toolbar_icon'] = 'Show toolbar icon (clear data/cache/* and browser cache if it\'s not displayed)';
+
+$lang['sortkey'] = 'sort topic lists by';
+$lang['sortkey_o_cdate'] = 'creation date';
+$lang['sortkey_o_mdate'] = 'modification date';
+$lang['sortkey_o_pagename'] = 'page name';
+$lang['sortkey_o_id'] = 'page ID';
+$lang['sortkey_o_ns'] = 'namespace';
+$lang['sortkey_o_title'] = 'title';
+
+$lang['sortorder'] = 'sort order';
+$lang['sortorder_o_ascending'] = 'ascending';
+$lang['sortorder_o_descending'] = 'descending';
+
+$lang['pagelist_flags'] = 'Formatting flags for the taglist (comma-separated, for available flags see the documentation of the Pagelist Plugin)';
+
+$lang['list_tags_of_subns'] = 'List also tags in subnamespaces of a specified namespace (count syntax)';
+
+$lang['tags_list_css'] = 'Choose style applied to pages\' tags list';
+$lang['tags_list_css_o_tags'] = 'default style';
+$lang['tags_list_css_o_tagstop'] = 'optimized for tags list at top of page';
diff --git a/platform/www/lib/plugins/tag/lang/eo/lang.php b/platform/www/lib/plugins/tag/lang/eo/lang.php
new file mode 100644
index 0000000..d9a4eeb
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/eo/lang.php
@@ -0,0 +1,19 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Ljosxa <ka2pink@gmail.com>
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['tag'] = 'Marko';
+$lang['tags'] = 'Markoj';
+$lang['topic'] = 'Temo';
+$lang['count'] = 'Kvanto';
+$lang['toolbar_icon'] = 'Enmeti Marko-sintakson';
+$lang['empty_output'] = 'Malplenigi Eligon';
+
+$lang['include'] = 'Inkluzivi';
+$lang['exclude'] = 'Ekskluzivi';
+$lang['use_and'] = 'Uzi logikon AND';
+$lang['no_tags'] = 'Neniuj markoj trovitaj';
diff --git a/platform/www/lib/plugins/tag/lang/eo/settings.php b/platform/www/lib/plugins/tag/lang/eo/settings.php
new file mode 100644
index 0000000..4d011fc
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/eo/settings.php
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Ljosxa <ka2pink@gmail.com>
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['namespace'] = 'Kutima nomospaco por markoj';
+$lang['toolbar_icon'] = 'Vidigi ilaran ikonon (nuligu data/cache/* kaj foliumilan kasxmemoron se gxi ne aperis)';
+
+$lang['sortkey'] = 'ordigi tem-liston laux';
+$lang['sortkey_o_cdate'] = 'dato de kreo';
+$lang['sortkey_o_mdate'] = 'dato de modifo';
+$lang['sortkey_o_pagename'] = 'nomo de pagxo';
+$lang['sortkey_o_id'] = 'pagxa ID';
+$lang['sortkey_o_ns'] = 'nomospaco';
+$lang['sortkey_o_title'] = 'temo';
+
+$lang['sortorder'] = 'ordigo';
+$lang['sortorder_o_ascending'] = 'kreskanta';
+$lang['sortorder_o_descending'] = 'malkreskanta';
+
+$lang['pagelist_flags'] = 'Formatigaj flagoj por marko-listo (perkome disigita, uzataj flagoj vidu en priskribo de kromprogramo "Pagelist")';
+
+$lang['list_tags_of_subns'] = 'Listigi ankaux markoj en subnomospacoj de indikita nomospaco ("count" sintakso)';
+
+$lang['tags_list_css'] = 'Elektu stilon aplikitan al la listo de etikedoj de paĝoj';
+$lang['tags_list_css_o_tags'] = 'defaŭlta stilo';
+$lang['tags_list_css_o_tagstop'] = 'optimumigita por listo de etikedoj supre de paĝo';
diff --git a/platform/www/lib/plugins/tag/lang/es/lang.php b/platform/www/lib/plugins/tag/lang/es/lang.php
new file mode 100644
index 0000000..0aab6dd
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/es/lang.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Domingo Redal <docxml@gmail.com>
+ * @author Digna González Otero <digna.gonzalezotero [at] gmail [dot] com>
+ * @author Camilo Sampedro <sampedro1903@gmail.com>
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['tag'] = 'Etiqueta';
+$lang['tags'] = 'Etiquetas';
+$lang['topic'] = 'Tema';
+$lang['count'] = 'Cantidad';
+$lang['toolbar_icon'] = 'Insertar sintaxis de etiqueta';
+$lang['empty_output'] = 'Salida vacía';
+
+$lang['include'] = 'Incluir';
+$lang['exclude'] = 'Excluir';
+$lang['use_and'] = 'Use lógica AND';
+$lang['no_tags'] = 'Ninguna etiqueta encontrada';
diff --git a/platform/www/lib/plugins/tag/lang/es/settings.php b/platform/www/lib/plugins/tag/lang/es/settings.php
new file mode 100644
index 0000000..10a012f
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/es/settings.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Digna González Otero <digna.gonzalezotero [at] gmail [dot] com>
+ * @author Camilo Sampedro <sampedro1903@gmail.com>
+ * @author Domingo Redal <docxml@gmail.com>
+ */
+
+$lang['namespace'] = 'Espacio de nombres por defecto para las etiquetas';
+$lang['toolbar_icon'] = 'Mostrar el ícono en la barra (borra data/cache/ y el caché del navegador si no es visible)';
+
+$lang['sortkey'] = 'ordenar las listas de temas por';
+$lang['sortkey_o_cdate'] = 'fecha de creación';
+$lang['sortkey_o_mdate'] = 'fecha de modificación';
+$lang['sortkey_o_pagename'] = 'nombre de la página';
+$lang['sortkey_o_id'] = 'ID de la página';
+$lang['sortkey_o_ns'] = 'nombre de espacio';
+$lang['sortkey_o_title'] = 'título';
+
+$lang['sortorder'] = 'tipo de ordenación';
+$lang['sortorder_o_ascending'] = 'ascendente';
+$lang['sortorder_o_descending'] = 'descendente';
+
+$lang['pagelist_flags'] = 'Dándole formato para la lista de etiquetas (separadas por coma, para ver los banderas (flags) consultar la documentación del plugin)';
+
+$lang['list_tags_of_subns'] = 'Listar también etiquetas en subespacios de nombre en un espacio de nombre específico (recuento de sintaxis)';
+
+$lang['tags_list_css'] = 'Elija el estilo aplicado a la página de lista de etiquetas';
+$lang['tags_list_css_o_tags'] = 'estilo por defecto';
+$lang['tags_list_css_o_tagstop'] = 'optimizado para la lista de etiquetas en la parte superior de la página';
diff --git a/platform/www/lib/plugins/tag/lang/fa/lang.php b/platform/www/lib/plugins/tag/lang/fa/lang.php
new file mode 100644
index 0000000..30086c3
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/fa/lang.php
@@ -0,0 +1,19 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author sam01 <m.sajad079@gmail.com>
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['tag'] = 'برچسب';
+$lang['tags'] = 'برچسب‌ها';
+$lang['topic'] = 'موضوع';
+$lang['count'] = 'مقدار';
+$lang['toolbar_icon'] = 'درج نحوهٔ ترکیب برچسب';
+$lang['empty_output'] = 'خروجی خالی';
+
+$lang['include'] = 'عبارتند از';
+$lang['exclude'] = 'محروم کردن';
+$lang['use_and'] = 'از منطق AND استفاده کنید';
+$lang['no_tags'] = 'برچسبی یافت نشد';
diff --git a/platform/www/lib/plugins/tag/lang/fa/settings.php b/platform/www/lib/plugins/tag/lang/fa/settings.php
new file mode 100644
index 0000000..50578e8
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/fa/settings.php
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author sam01 <m.sajad079@gmail.com>
+ */
+
+$lang['namespace'] = 'فضای نام پیشفرض برای برچسب‌ها';
+$lang['toolbar_icon'] = 'آیکون نمایش نوار ابزار (پاک کردن اطلاعات/کش/ * و کش مرورگر اگر چیزی نمایش داده نمی‌شود)';
+
+$lang['sortkey'] = 'مرتب‌ سازی لیست موضوع توسط';
+$lang['sortkey_o_cdate'] = 'تاریخ ایجاد';
+$lang['sortkey_o_mdate'] = 'تاریخ اصلاح';
+$lang['sortkey_o_pagename'] = 'نام صفحه';
+$lang['sortkey_o_id'] = 'آیدی صفحه';
+$lang['sortkey_o_ns'] = 'فضای نام';
+$lang['sortkey_o_title'] = 'عنوان';
+
+$lang['sortorder'] = 'مرتب سازی سفارشی';
+$lang['sortorder_o_ascending'] = 'صعودی';
+$lang['sortorder_o_descending'] = 'نزولی';
+
+$lang['pagelist_flags'] = 'پرچم قالب بندی برای لیست برچسب‌ها (جداکردن با کاما، برای پرچم‌های موجود اسناد لیست صفحه‌ای پلاگین را ببینید)';
+
+$lang['list_tags_of_subns'] = 'لیست برچسب‌ها در فضاهای فرعی از یک فضای نام خاص (تعداد نحوهٔ ترکیب)';
+
+$lang['tags_list_css'] = 'انتخاب سبک اعمال شده‌ی صفحات \' لیست برچسب‌ها';
+$lang['tags_list_css_o_tags'] = 'سبک پیش‌فرض';
+$lang['tags_list_css_o_tagstop'] = 'بهینه سازی شده برای لیست برچسب‌ها در بالای صفحه';
diff --git a/platform/www/lib/plugins/tag/lang/fi/lang.php b/platform/www/lib/plugins/tag/lang/fi/lang.php
new file mode 100644
index 0000000..6aa382f
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/fi/lang.php
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['tag'] = 'Tunniste';
+$lang['tags'] = 'Tunnisteet';
+$lang['topic'] = 'Aihe';
+$lang['count'] = 'Määrä';
+$lang['toolbar_icon'] = 'Lisää tunniste-syntakse';
+$lang['empty_output'] = 'Tyhjä tulos';
+
+$lang['include'] = 'Sisällytä';
+$lang['exclude'] = 'Sulje pois';
+$lang['use_and'] = 'Käytä logiikkaa JA';
+$lang['no_tags'] = 'Tunnisteita ei löytynyt';
diff --git a/platform/www/lib/plugins/tag/lang/fi/settings.php b/platform/www/lib/plugins/tag/lang/fi/settings.php
new file mode 100644
index 0000000..ba8c9bf
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/fi/settings.php
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['namespace'] = 'Tunnisteiden oletusnimitila';
+$lang['toolbar_icon'] = 'Näytä työkalurivin kuvake (tyhjennä data/cache/* ja selaimen välimuisti, jos sitä ei näy)';
+
+$lang['sortkey'] = 'lajittele aiheluettelot';
+$lang['sortkey_o_cdate'] = 'luomispäivä';
+$lang['sortkey_o_mdate'] = 'muokkauspäivä';
+$lang['sortkey_o_pagename'] = 'sivun nimi';
+$lang['sortkey_o_id'] = 'sivun tunnus';
+$lang['sortkey_o_ns'] = 'nimitila';
+$lang['sortkey_o_title'] = 'otsikko';
+
+$lang['sortorder'] = 'lajittelujärjestys';
+$lang['sortorder_o_ascending'] = 'nouseva';
+$lang['sortorder_o_descending'] = 'laskeva';
+
+$lang['pagelist_flags'] = 'Tagilistan lippujen muotoilu (pilkuilla erotettu, saatavilla olevat liput katso sivulista-laajennuksen ohjeista)';
+
+$lang['list_tags_of_subns'] = 'Luettele myös tunnisteet määritetyn nimiavaruuden alitunnustiloissa (laskesyntaksi)';
+
+$lang['tags_list_css'] = 'Valitse sivujen tunnisteiden luetteloon käytetty tyyli';
+$lang['tags_list_css_o_tags'] = 'oletustyyli';
+$lang['tags_list_css_o_tagstop'] = 'optimoitu tunnisteiden luetteloon sivun yläosassa';
diff --git a/platform/www/lib/plugins/tag/lang/fr/lang.php b/platform/www/lib/plugins/tag/lang/fr/lang.php
new file mode 100644
index 0000000..553ead4
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/fr/lang.php
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Nicolas Friedli <nicolas@theologique.ch>
+ * @author Schplurtz le Déboulonné <Schplurtz@laposte.net>
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['tag'] = 'Étiquette';
+$lang['tags'] = 'Étiquettes';
+$lang['topic'] = 'Sujet';
+$lang['count'] = 'Quantité';
+$lang['toolbar_icon'] = 'Insérer des étiquettes';
+$lang['empty_output'] = 'Pas de résultat';
+
+$lang['include'] = 'Inclure';
+$lang['exclude'] = 'Exclure';
+$lang['use_and'] = 'Utiliser la logique AND';
+$lang['no_tags'] = 'Aucune étiquette trouvée';
diff --git a/platform/www/lib/plugins/tag/lang/fr/settings.php b/platform/www/lib/plugins/tag/lang/fr/settings.php
new file mode 100644
index 0000000..4163860
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/fr/settings.php
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Damien Raude-Morvan <drazzib@drazzib.com>
+ * @author Stanislas Reltgen <stanislas@reltgen.net>
+ * @author NicolasFriedli <nicolas@theologique.ch>
+ * @author Olivier Humbert <trebmuh@tuxfamily.org>
+ * @author Schplurtz le Déboulonné <Schplurtz@laposte.net>
+ */
+
+$lang['namespace'] = 'Dossier par défaut pour les étiquettes';
+$lang['toolbar_icon'] = 'Afficher l\'icône dans la barre d\'outils (purger data/cache/* et le cache du navigateur si il n\'apparait pas)';
+
+$lang['sortkey'] = 'trier par&nbsp;:';
+$lang['sortkey_o_cdate'] = 'date de création';
+$lang['sortkey_o_mdate'] = 'date de modification';
+$lang['sortkey_o_pagename'] = 'nom de la page';
+$lang['sortkey_o_id'] = 'ID de la page';
+$lang['sortkey_o_ns'] = 'catégorie';
+$lang['sortkey_o_title'] = 'titre';
+
+$lang['sortorder'] = 'ordre';
+$lang['sortorder_o_ascending'] = 'croissant';
+$lang['sortorder_o_descending'] = 'décroissant';
+
+$lang['pagelist_flags'] = 'Paramètres d\'affichage pour lister les pages (séparés par des virgules, pour la liste des paramètres voir la documentation du greffon pagelist)';
+
+$lang['list_tags_of_subns'] = 'Lister les étiquettes présentes aussi dans les sous-dossiers (syntaxe count)';
+
+$lang['tags_list_css'] = 'Style appliqué à la liste de étiquettes des pages';
+$lang['tags_list_css_o_tags'] = 'style par défaut';
+$lang['tags_list_css_o_tagstop'] = 'optimisé pour les listes d\'étiquettes en haut de page';
diff --git a/platform/www/lib/plugins/tag/lang/he/lang.php b/platform/www/lib/plugins/tag/lang/he/lang.php
new file mode 100644
index 0000000..d7f5a06
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/he/lang.php
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['tag'] = 'תייג';
+$lang['tags'] = 'תגים';
+$lang['topic'] = 'נושא';
+$lang['count'] = 'כַּמוּת';
+$lang['toolbar_icon'] = 'הוסף תחביר תג';
+$lang['empty_output'] = 'פלט ריק';
+
+$lang['include'] = 'לִכלוֹל';
+$lang['exclude'] = 'אל תכלול';
+$lang['use_and'] = 'השתמש בהיגיון AND';
+$lang['no_tags'] = 'לא נמצאו תגים';
diff --git a/platform/www/lib/plugins/tag/lang/he/settings.php b/platform/www/lib/plugins/tag/lang/he/settings.php
new file mode 100644
index 0000000..f1613ec
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/he/settings.php
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['namespace'] = 'מרחב שמות ברירת מחדל לתגים';
+$lang['toolbar_icon'] = 'הצג את סמל סרגל הכלים (נקה "data/cache/*" ומטמון הדפדפן אם הוא לא מוצג)';
+
+$lang['sortkey'] = 'מיין רשימות נושאים לפי';
+$lang['sortkey_o_cdate'] = 'תאריך יצירה';
+$lang['sortkey_o_mdate'] = 'תאריך שינוי';
+$lang['sortkey_o_pagename'] = 'שם העמוד';
+$lang['sortkey_o_id'] = 'מזהה דף';
+$lang['sortkey_o_ns'] = 'מרחב שמות';
+$lang['sortkey_o_title'] = 'כותרת';
+
+$lang['sortorder'] = 'סדר מיון';
+$lang['sortorder_o_ascending'] = 'עולה';
+$lang['sortorder_o_descending'] = 'יורד';
+
+$lang['pagelist_flags'] = 'עיצוב דגלים עבור רשימת התגים (מופרדים בפסיקים, לקבלת דגלים זמינים עיין בתיעוד של תוסף ה- Pagelist)';
+
+$lang['list_tags_of_subns'] = 'רשום גם תגים במרחבי משנה של מרחב שמות מוגדר (תחביר ספירה)';
+
+$lang['tags_list_css'] = 'בחר סגנון שהוחל על רשימת התגים של הדפים';
+$lang['tags_list_css_o_tags'] = 'סגנון ברירת מחדל';
+$lang['tags_list_css_o_tagstop'] = 'מותאם לרשימת התגים בראש העמוד';
diff --git a/platform/www/lib/plugins/tag/lang/hi/lang.php b/platform/www/lib/plugins/tag/lang/hi/lang.php
new file mode 100644
index 0000000..e05a061
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/hi/lang.php
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['tag'] = 'टैग';
+$lang['tags'] = 'टैग';
+$lang['topic'] = 'विषय';
+$lang['count'] = 'मात्रा';
+$lang['toolbar_icon'] = 'टैग-सिंटैक्स डालें';
+$lang['empty_output'] = 'खाली आउटपुट';
+
+$lang['include'] = 'शामिल';
+$lang['exclude'] = 'निकालना';
+$lang['use_and'] = 'तर्क का उपयोग करें AND';
+$lang['no_tags'] = 'कोई टैग नहीं मिला';
diff --git a/platform/www/lib/plugins/tag/lang/hi/settings.php b/platform/www/lib/plugins/tag/lang/hi/settings.php
new file mode 100644
index 0000000..f987b42
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/hi/settings.php
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['namespace'] = 'टैग्स के लिए डिफॉल्ट नेमस्पेस';
+$lang['toolbar_icon'] = 'टूलबार आइकन दिखाएं (स्पष्ट data/cache/* और ब्राउज़र कैश यदि यह प्रदर्शित नहीं है)';
+
+$lang['sortkey'] = 'सॉर्ट टॉपिक लिस्ट बाय';
+$lang['sortkey_o_cdate'] = 'निर्माण तिथि';
+$lang['sortkey_o_mdate'] = 'संशोधन तिथि';
+$lang['sortkey_o_pagename'] = 'पेज नाम';
+$lang['sortkey_o_id'] = 'पेज ID';
+$lang['sortkey_o_ns'] = 'नेमस्पेस';
+$lang['sortkey_o_title'] = 'शीर्षक';
+
+$lang['sortorder'] = 'सॉर्ट ऑर्डर';
+$lang['sortorder_o_ascending'] = 'आरोही';
+$lang['sortorder_o_descending'] = 'अवरोही';
+
+$lang['pagelist_flags'] = 'टैगलिस्ट के लिए झंडे का प्रारूपण (अल्पविराम से अलग किए गए, उपलब्ध झंडे के लिए Pagelist Plugin) का प्रलेखन देखें ';
+
+$lang['list_tags_of_subns'] = 'एक निर्दिष्ट नामस्थान (गिनती सिंटैक्स) के उप-नामों में भी टैग';
+
+$lang['tags_list_css'] = 'पृष्ठों की टैग सूची में लागू शैली चुनें';
+$lang['tags_list_css_o_tags'] = 'डिफ़ॉल्ट शैली';
+$lang['tags_list_css_o_tagstop'] = 'पृष्ठ के शीर्ष पर टैग सूची के लिए अनुकूलित';
diff --git a/platform/www/lib/plugins/tag/lang/hr/lang.php b/platform/www/lib/plugins/tag/lang/hr/lang.php
new file mode 100644
index 0000000..a12f485
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/hr/lang.php
@@ -0,0 +1,19 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Davor Turkalj <turki.bsc@gmail.com>
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['tag'] = 'Oznaka';
+$lang['tags'] = 'Oznake';
+$lang['topic'] = 'Teme';
+$lang['count'] = 'Količina';
+$lang['toolbar_icon'] = 'Ubaci sintaksu oznake';
+$lang['empty_output'] = 'Prazan izlaz';
+
+$lang['include'] = 'Uključi';
+$lang['exclude'] = 'Izuzmi';
+$lang['use_and'] = 'Koristi logiku AND';
+$lang['no_tags'] = 'Nema oznaka';
diff --git a/platform/www/lib/plugins/tag/lang/hr/settings.php b/platform/www/lib/plugins/tag/lang/hr/settings.php
new file mode 100644
index 0000000..03abd93
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/hr/settings.php
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Davor Turkalj <turki.bsc@gmail.com>
+ */
+
+$lang['namespace'] = 'Podrazumijevani imenski prostor za oznake';
+$lang['toolbar_icon'] = 'Prikaži ikonu na alatnoj traci (očisti data/cache/* i priručnu pohranu preglednika ako se ne prikazuje)';
+
+$lang['sortkey'] = 'poredaj listu tema po';
+$lang['sortkey_o_cdate'] = 'datum kreiranja';
+$lang['sortkey_o_mdate'] = 'datum promjene';
+$lang['sortkey_o_pagename'] = 'ime stranice';
+$lang['sortkey_o_id'] = 'oznaka stranice';
+$lang['sortkey_o_ns'] = 'imenski prostor';
+$lang['sortkey_o_title'] = 'naslov';
+
+$lang['sortorder'] = 'poredak';
+$lang['sortorder_o_ascending'] = 'rastući';
+$lang['sortorder_o_descending'] = 'padajući';
+
+$lang['pagelist_flags'] = 'zastavice oblikovanja za listu oznaka (zarezom odvojene, za listu dostupnih zastavica vidi dokumentaciju dodatka pagelist)';
+
+$lang['list_tags_of_subns'] = 'Prikaži također oznake iz pod-imeničkih prostora specificiranog imeničkog prostora';
+
+$lang['tags_list_css'] = 'Odaberi stil primijenjen na liste oznaka';
+$lang['tags_list_css_o_tags'] = 'podrazumijevani stil';
+$lang['tags_list_css_o_tagstop'] = 'optimirano za listu oznaka na vrhu stranice';
diff --git a/platform/www/lib/plugins/tag/lang/hu/lang.php b/platform/www/lib/plugins/tag/lang/hu/lang.php
new file mode 100644
index 0000000..f6f3518
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/hu/lang.php
@@ -0,0 +1,19 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Marina Vladi <deldadam@gmail.com>
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['tag'] = 'Címké';
+$lang['tags'] = 'Címkék';
+$lang['topic'] = 'Téma';
+$lang['count'] = 'Mennyiség';
+$lang['toolbar_icon'] = 'Címkeszintaxis beillesztése';
+$lang['empty_output'] = 'Üres kimenet';
+
+$lang['include'] = 'Beleértve';
+$lang['exclude'] = 'Kivéve';
+$lang['use_and'] = 'Használja a logikát AND';
+$lang['no_tags'] = 'Nincsenek címkék';
diff --git a/platform/www/lib/plugins/tag/lang/hu/settings.php b/platform/www/lib/plugins/tag/lang/hu/settings.php
new file mode 100644
index 0000000..86886e6
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/hu/settings.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Norbert Csík <norbert.csik@gmail.com>
+ * @author Marina Vladi <deldadam@gmail.com>
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['namespace'] = 'Címkék alapértelmezett névtere';
+$lang['toolbar_icon'] = 'Ikon megjelenítése eszközsoron (töröljük az adat-* és böngésző gyorsítótárat, ha nem jelenne meg)';
+
+$lang['sortkey'] = 'Témalista rendezési módja';
+$lang['sortkey_o_cdate'] = 'készítés dátuma';
+$lang['sortkey_o_mdate'] = 'módosítás dátuma';
+$lang['sortkey_o_pagename'] = 'oldalnév';
+$lang['sortkey_o_id'] = 'oldalazonosító (ID)';
+$lang['sortkey_o_ns'] = 'névtér';
+$lang['sortkey_o_title'] = 'cím';
+
+$lang['sortorder'] = 'Rendezés iránya';
+$lang['sortorder_o_ascending'] = 'növekvő';
+$lang['sortorder_o_descending'] = 'csökkenő';
+
+$lang['pagelist_flags'] = 'Formátumozó beállítások a címkelistához (vesszővel elválasztva, az elérhető beállításokat nézzük meg a pagelist bővítmény dokumentációjában)';
+
+$lang['list_tags_of_subns'] = 'Adott névtér alnévtereiben szereplő címkék listázása (számláló szintaxis)';
+
+$lang['tags_list_css'] = 'Válassza ki az oldalak címkék listájára alkalmazott stílust';
+$lang['tags_list_css_o_tags'] = 'alapértelmezett stílus';
+$lang['tags_list_css_o_tagstop'] = 'címkékhez optimalizált oldal tetején';
diff --git a/platform/www/lib/plugins/tag/lang/id/lang.php b/platform/www/lib/plugins/tag/lang/id/lang.php
new file mode 100644
index 0000000..363f801
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/id/lang.php
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['tag'] = 'Tag';
+$lang['tags'] = 'Tag';
+$lang['topic'] = 'Topik';
+$lang['count'] = 'Kuantitas';
+$lang['toolbar_icon'] = 'Sisipkan Sintaksis Tag';
+$lang['empty_output'] = 'Output Kosong';
+
+$lang['include'] = 'Sertakan';
+$lang['exclude'] = 'Mengecualikan';
+$lang['use_and'] = 'Gunakan logika AND';
+$lang['no_tags'] = 'Tidak ditemukan tag';
diff --git a/platform/www/lib/plugins/tag/lang/id/settings.php b/platform/www/lib/plugins/tag/lang/id/settings.php
new file mode 100644
index 0000000..5052955
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/id/settings.php
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['namespace'] = 'Ruang nama default untuk tag';
+$lang['toolbar_icon'] = 'Tampilkan ikon toolbar (hapus data/cache/* dan cache browser jika tidak ditampilkan)';
+
+$lang['sortkey'] = 'urutkan daftar topik berdasarkan';
+$lang['sortkey_o_cdate'] = 'tanggal pembuatan';
+$lang['sortkey_o_mdate'] = 'tanggal modifikasi';
+$lang['sortkey_o_pagename'] = 'nama halaman';
+$lang['sortkey_o_id'] = 'ID halaman';
+$lang['sortkey_o_ns'] = 'ruang nama';
+$lang['sortkey_o_title'] = 'judul';
+
+$lang['sortorder'] = 'tata urutan';
+$lang['sortorder_o_ascending'] = 'naik';
+$lang['sortorder_o_descending'] = 'turun';
+
+$lang['pagelist_flags'] = 'Memformat flag untuk daftar tag (dipisahkan koma, untuk flag yang tersedia lihat dokumentasi dari Plugin Pagelist)';
+
+$lang['list_tags_of_subns'] = 'Daftar juga tag dalam ruang subnama dari ruang nama tertentu (sintaks hitung)';
+
+$lang['tags_list_css'] = 'Pilih gaya yang diterapkan ke halaman\' daftar tag';
+$lang['tags_list_css_o_tags'] = 'gaya standar';
+$lang['tags_list_css_o_tagstop'] = 'dioptimalkan untuk daftar tag di bagian atas halaman';
diff --git a/platform/www/lib/plugins/tag/lang/it/lang.php b/platform/www/lib/plugins/tag/lang/it/lang.php
new file mode 100644
index 0000000..5f4b0a1
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/it/lang.php
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['tag'] = 'Tag';
+$lang['tags'] = 'Tag';
+$lang['topic'] = 'Argomento';
+$lang['count'] = 'Quantità';
+$lang['toolbar_icon'] = 'Inserisci la sintassi tag';
+$lang['empty_output'] = 'Output vuoto';
+
+$lang['include'] = 'Includi';
+$lang['exclude'] = 'Escludi';
+$lang['use_and'] = 'Usa logica AND';
+$lang['no_tags'] = 'Nessun tag trovato';
diff --git a/platform/www/lib/plugins/tag/lang/it/settings.php b/platform/www/lib/plugins/tag/lang/it/settings.php
new file mode 100644
index 0000000..a05c296
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/it/settings.php
@@ -0,0 +1,29 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Roberto Bellingeri <bellingeri@netguru.it>
+ */
+$lang['namespace'] = 'Namespace predefinito per i tag';
+$lang['toolbar_icon'] = 'Mostra l\'icona della barra degli strumenti (cancella dati/cache/* e la cache del browser se non viene visualizzata)';
+
+$lang['sortkey'] = 'ordina gli elenchi di argomenti per';
+$lang['sortkey_o_cdate'] = 'data di creazione';
+$lang['sortkey_o_mdate'] = 'data di modifica';
+$lang['sortkey_o_pagename'] = 'nome della pagina';
+$lang['sortkey_o_id'] = 'ID della pagina';
+$lang['sortkey_o_ns'] = 'namespace';
+$lang['sortkey_o_title'] = 'titolo';
+
+$lang['sortorder'] = 'ordinamento';
+$lang['sortorder_o_ascending'] = 'crescente';
+$lang['sortorder_o_descending'] = 'decrescente';
+
+$lang['pagelist_flags'] = 'Formattazione dei flag per l\'elenco di tag (separati da virgola, per i flag disponibili vedere la documentazione del plug-in Pagelist)';
+
+$lang['list_tags_of_subns'] = 'Elenca anche i tag nei sottomenu di uno spazio dei nomi specificato (sintassi conteggio)';
+
+$lang['tags_list_css'] = 'Scegli lo stile applicato all\'elenco dei tag delle pagine';
+$lang['tags_list_css_o_tags'] = 'stile predefinito';
+$lang['tags_list_css_o_tagstop'] = 'ottimizzato per l\'elenco di tag nella parte superiore della pagina';
diff --git a/platform/www/lib/plugins/tag/lang/ja/lang.php b/platform/www/lib/plugins/tag/lang/ja/lang.php
new file mode 100644
index 0000000..ac2b615
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/ja/lang.php
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Ikuo Obataya <cxx05051@nifty.com>
+ * @author Hideaki SAWADA <chuno@live.jp>
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['tag'] = 'タグ';
+$lang['tags'] = 'タグ';
+$lang['topic'] = 'トピック';
+$lang['count'] = '数量';
+$lang['toolbar_icon'] = 'タグ構文の挿入';
+$lang['empty_output'] = '空の出力';
+
+$lang['include'] = '含む';
+$lang['exclude'] = '除外する';
+$lang['use_and'] = 'ロジック AND 検索';
+$lang['no_tags'] = 'タグがありません';
diff --git a/platform/www/lib/plugins/tag/lang/ja/settings.php b/platform/www/lib/plugins/tag/lang/ja/settings.php
new file mode 100644
index 0000000..16851b6
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/ja/settings.php
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Ikuo Obataya <cxx05051@nifty.com>
+ * @author Hideaki SAWADA <chuno@live.jp>
+ */
+
+$lang['namespace'] = 'タグのデフォルト名前空間';
+$lang['toolbar_icon'] = 'ツールバーボタンを表示(表示されない場合、data/cache/* とブラウザキャッシュを削除)';
+
+$lang['sortkey'] = 'topic 一覧のソート基準';
+$lang['sortkey_o_cdate'] = '作成日';
+$lang['sortkey_o_mdate'] = '更新日';
+$lang['sortkey_o_pagename'] = 'ページ名';
+$lang['sortkey_o_id'] = 'ページ ID';
+$lang['sortkey_o_ns'] = '名前空間';
+$lang['sortkey_o_title'] = 'タイトル';
+
+$lang['sortorder'] = 'ソート順';
+$lang['sortorder_o_ascending'] = '昇順';
+$lang['sortorder_o_descending'] = '降順';
+
+$lang['pagelist_flags'] = 'タグリストの表示フラグ(カンマ区切り。使用可能フラグは pagelist プラグインを参照)';
+
+$lang['list_tags_of_subns'] = '指定名前空間の下位の名前空間のタグも一覧に含む(count 構文)';
+
+$lang['tags_list_css'] = 'ページタグ一覧に適用されるスタイルを選択してください。';
+$lang['tags_list_css_o_tags'] = 'デフォルトスタイル';
+$lang['tags_list_css_o_tagstop'] = 'ページ上部配置に最適化';
diff --git a/platform/www/lib/plugins/tag/lang/ko/lang.php b/platform/www/lib/plugins/tag/lang/ko/lang.php
new file mode 100644
index 0000000..9a98a4c
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/ko/lang.php
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Myeongjin <aranet100@gmail.com>
+ * @author dryoo <dryoo@live.com>
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['tag'] = '태그';
+$lang['tags'] = '태그';
+$lang['topic'] = '주제';
+$lang['count'] = '수량';
+$lang['toolbar_icon'] = '태그 문법 넣기';
+$lang['empty_output'] = '빈 출력';
+
+$lang['include'] = '포함';
+$lang['exclude'] = '제외';
+$lang['use_and'] = '논리 AND 사용';
+$lang['no_tags'] = '찾은 태그 없음';
diff --git a/platform/www/lib/plugins/tag/lang/ko/settings.php b/platform/www/lib/plugins/tag/lang/ko/settings.php
new file mode 100644
index 0000000..8deed83
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/ko/settings.php
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Myeongjin <aranet100@gmail.com>
+ */
+
+$lang['namespace'] = '태그에 대한 기본 이름공간';
+$lang['toolbar_icon'] = '도구 모음 아이콘 보이기 (표시되지 않으면 data/cache/* 와 브라우저 캐시를 지우세요)';
+
+$lang['sortkey'] = '주제 목록 정렬 기준';
+$lang['sortkey_o_cdate'] = '만든 날짜';
+$lang['sortkey_o_mdate'] = '수정한 날짜';
+$lang['sortkey_o_pagename'] = '문서 이름';
+$lang['sortkey_o_id'] = '문서 ID';
+$lang['sortkey_o_ns'] = '이름공간';
+$lang['sortkey_o_title'] = '제목';
+
+$lang['sortorder'] = '정렬 순서';
+$lang['sortorder_o_ascending'] = '오름차순';
+$lang['sortorder_o_descending'] = '내림차순';
+
+$lang['pagelist_flags'] = '태그 목록에 대한 서식 플래그 (쉼표로 구분, 사용할 수 있는 플래그에 대해서는 Pagelist 플러그인의 설명문서를 보세요)';
+
+$lang['list_tags_of_subns'] = '지정된 이름공간의 하위 이름공간에 있는 태그도 나열 (개수 문법)';
+
+$lang['tags_list_css'] = '문서의 태그 목록에 적용할 스타일 선택';
+$lang['tags_list_css_o_tags'] = '기본 스타일';
+$lang['tags_list_css_o_tagstop'] = '문서 위에 있는 태그 목록에 최적화';
diff --git a/platform/www/lib/plugins/tag/lang/nl/lang.php b/platform/www/lib/plugins/tag/lang/nl/lang.php
new file mode 100644
index 0000000..510829b
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/nl/lang.php
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Gerrit Uitslag <klapinklapin@gmail.com>
+ * @author Joachim David <joachim.david@teka-infopilots.com>
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['tag'] = 'Tag';
+$lang['tags'] = 'Tags';
+$lang['topic'] = 'Onderwerp';
+$lang['count'] = 'Hoeveelheid';
+$lang['toolbar_icon'] = 'Tag-syntax invoegen';
+$lang['empty_output'] = 'Uitvoer leegmaken';
+
+$lang['include'] = 'Inclusief';
+$lang['exclude'] = 'Exclusief';
+$lang['use_and'] = 'Gebruik logica AND';
+$lang['no_tags'] = 'Geen tags gevonden';
diff --git a/platform/www/lib/plugins/tag/lang/nl/settings.php b/platform/www/lib/plugins/tag/lang/nl/settings.php
new file mode 100644
index 0000000..25db10d
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/nl/settings.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Gerrit Uitslag <klapinklapin@gmail.com>
+ * @author Peter van Diest <peter.van.diest@xs4all.nl>
+ * @author Joachim David <joachim.david@teka-infopilots.com>
+ */
+
+$lang['namespace'] = 'Standaard namespace voor tags';
+$lang['toolbar_icon'] = 'Toon knop in de werkbalk (leeg data/cache/* en browser cache als hij niet wordt getoond)';
+
+$lang['sortkey'] = 'sorteer onderwerpenlijsten op';
+$lang['sortkey_o_cdate'] = 'aanmaakdatum';
+$lang['sortkey_o_mdate'] = 'bewerkdatum';
+$lang['sortkey_o_pagename'] = 'paginanaam';
+$lang['sortkey_o_id'] = 'pagina-id';
+$lang['sortkey_o_ns'] = 'namespace';
+$lang['sortkey_o_title'] = 'titel';
+
+$lang['sortorder'] = 'sorteervolgorde';
+$lang['sortorder_o_ascending'] = 'oplopend';
+$lang['sortorder_o_descending'] = 'aflopend';
+
+$lang['pagelist_flags'] = 'Opmaakvlaggen voor de taglijst (gescheiden door komma\'s, voor beschikbare vlaggen zie documentatie van de Pagelist plugin)';
+
+$lang['list_tags_of_subns'] = 'Als er op een specifieke namespace wordt gezocht, geef dan in de lijst ook tags uit subnamespaces van deze specifieke namespace (count syntax)';
+
+$lang['tags_list_css'] = 'Kies een stijl voor de lijst van tags voor de pagina';
+$lang['tags_list_css_o_tags'] = 'standaardstijl';
+$lang['tags_list_css_o_tagstop'] = 'geoptimaliseerd voor een lijst van tags bovenaan de pagina';
diff --git a/platform/www/lib/plugins/tag/lang/pl/lang.php b/platform/www/lib/plugins/tag/lang/pl/lang.php
new file mode 100644
index 0000000..5708280
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/pl/lang.php
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['tag'] = 'Tag';
+$lang['tags'] = 'Tagi';
+$lang['topic'] = 'Temat';
+$lang['count'] = 'Ilość';
+$lang['toolbar_icon'] = 'Wstaw składnię tagu';
+$lang['empty_output'] = 'Puste wyjście';
+
+$lang['include'] = 'Uwzględnić';
+$lang['exclude'] = 'Wykluczyć';
+$lang['use_and'] = 'Użyj logiki AND';
+$lang['no_tags'] = 'Nie znaleziono tagów';
diff --git a/platform/www/lib/plugins/tag/lang/pl/settings.php b/platform/www/lib/plugins/tag/lang/pl/settings.php
new file mode 100644
index 0000000..6700c5e
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/pl/settings.php
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Bartek S <sadupl@gmail.com>
+ */
+
+$lang['namespace'] = 'Domyślna przestrzeń nazw dla tagów';
+$lang['toolbar_icon'] = 'Pokaż ikonę paska narzędzi (wyczyść dane / pamięć podręczną / * i pamięć podręczną przeglądarki, jeśli nie są wyświetlane)';
+
+$lang['sortkey'] = 'sortuj listy tematów według';
+$lang['sortkey_o_cdate'] = 'data utworzenia';
+$lang['sortkey_o_mdate'] = 'data modyfikacji';
+$lang['sortkey_o_pagename'] = 'nazwa strony';
+$lang['sortkey_o_id'] = 'ID strony';
+$lang['sortkey_o_ns'] = 'przestrzeń nazw';
+$lang['sortkey_o_title'] = 'tytuł';
+
+$lang['sortorder'] = 'porządek sortowania';
+$lang['sortorder_o_ascending'] = 'rosnąco';
+$lang['sortorder_o_descending'] = 'malejąco';
+
+$lang['pagelist_flags'] = 'Formatowanie flag dla taglist (oddzielone przecinkami, dostępne flagi znajdują się w dokumentacji wtyczki Pagelist)';
+
+$lang['list_tags_of_subns'] = 'Wyświetl także tagi w podprzestrzeniach określonej przestrzeni nazw (składnia licznika)';
+
+$lang['tags_list_css'] = 'Wybierz styl zastosowany do stron \' lista tagów';
+$lang['tags_list_css_o_tags'] = 'domyślny styl';
+$lang['tags_list_css_o_tagstop'] = 'zoptymalizowany pod kątem listy tagów u góry strony';
diff --git a/platform/www/lib/plugins/tag/lang/pt-br/lang.php b/platform/www/lib/plugins/tag/lang/pt-br/lang.php
new file mode 100644
index 0000000..c5313c7
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/pt-br/lang.php
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['tag'] = 'Tag';
+$lang['tags'] = 'Tags';
+$lang['topic'] = 'Tópico';
+$lang['count'] = 'Quantidade';
+$lang['toolbar_icon'] = 'Inserir tag-sintaxe';
+$lang['empty_output'] = 'Saída vazia';
+
+$lang['include'] = 'Incluir';
+$lang['exclude'] = 'Excluir';
+$lang['use_and'] = 'Usar lógica AND';
+$lang['no_tags'] = 'Sem tags encontradas';
diff --git a/platform/www/lib/plugins/tag/lang/pt-br/settings.php b/platform/www/lib/plugins/tag/lang/pt-br/settings.php
new file mode 100644
index 0000000..32c59cb
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/pt-br/settings.php
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * Portuguese language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Flávio Roberto Santos <flavio.barata@gmail.com>
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['namespace'] = 'Namespace padrão para as tags';
+$lang['toolbar_icon'] = 'Mostrar ícone de barra de ferramentas (limpar dados/cache/* e cache do navegador se não for exibido)';
+
+$lang['sortkey'] = 'classificar listas de tópicos por';
+$lang['sortkey_o_cdate'] = 'data de criação';
+$lang['sortkey_o_mdate'] = 'data de modificação';
+$lang['sortkey_o_pagename'] = 'nome da página';
+$lang['sortkey_o_id'] = 'ID da página';
+$lang['sortkey_o_ns'] = 'namespace';
+$lang['sortkey_o_title'] = 'título';
+
+$lang['sortorder'] = 'ordem de classificação';
+$lang['sortorder_o_ascending'] = 'crescente';
+$lang['sortorder_o_descending'] = 'descendente';
+
+$lang['pagelist_flags'] = 'Formatação de bandeiras para o taglist (separado por círia, para bandeiras disponíveis, consulte a documentação do Plugin Pagelist)';
+
+$lang['list_tags_of_subns'] = 'Lista também tags em subnamespaces de um namespace especificado (conta sintaxe)';
+
+$lang['tags_list_css'] = 'Escolha o estilo aplicado à lista de tags das páginas';
+$lang['tags_list_css_o_tags'] = 'estilo padrão';
+$lang['tags_list_css_o_tagstop'] = 'otimizado para lista de tags no topo da página';
diff --git a/platform/www/lib/plugins/tag/lang/pt/lang.php b/platform/www/lib/plugins/tag/lang/pt/lang.php
new file mode 100644
index 0000000..3b6d954
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/pt/lang.php
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['tag'] = 'Tag';
+$lang['tags'] = 'Tags';
+$lang['topic'] = 'Tópico';
+$lang['count'] = 'Quantidade';
+$lang['toolbar_icon'] = 'Inserir sintaxe de tag';
+$lang['empty_output'] = 'Saída vazia';
+
+$lang['include'] = 'Incluir';
+$lang['exclude'] = 'Excluir';
+$lang['use_and'] = 'Use lógica AND';
+$lang['no_tags'] = 'Nenhuma tag encontrada';
diff --git a/platform/www/lib/plugins/tag/lang/pt/settings.php b/platform/www/lib/plugins/tag/lang/pt/settings.php
new file mode 100644
index 0000000..7bd1461
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/pt/settings.php
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['namespace'] = 'Espaço de nome padrão para tags';
+$lang['toolbar_icon'] = 'Mostrar ícone da barra de ferramentas (limpar data/cache/* e o cache do navegador se não estiver exibido)';
+
+$lang['sortkey'] = 'classificar listas de tópicos por';
+$lang['sortkey_o_cdate'] = 'data de criação';
+$lang['sortkey_o_mdate'] = 'data de modificação';
+$lang['sortkey_o_pagename'] = 'nome da página';
+$lang['sortkey_o_id'] = 'ID da página';
+$lang['sortkey_o_ns'] = 'espaço de nome';
+$lang['sortkey_o_title'] = 'título';
+
+$lang['sortorder'] = 'ordem de classificação';
+$lang['sortorder_o_ascending'] = 'ascendente';
+$lang['sortorder_o_descending'] = 'decrescente';
+
+$lang['pagelist_flags'] = 'Sinalizadores de formatação para a lista de tags (separados por vírgulas; para sinalizadores disponíveis, consulte a documentação do plugin Pagelist)';
+
+$lang['list_tags_of_subns'] = 'Listar também tags em subnamespaces de um namespace especificado (sintaxe de contagem)';
+
+$lang['tags_list_css'] = 'Escolha o estilo aplicado à lista de tags das páginas';
+$lang['tags_list_css_o_tags'] = 'estilo padrão';
+$lang['tags_list_css_o_tagstop'] = 'otimizado para lista de tags no topo da página';
diff --git a/platform/www/lib/plugins/tag/lang/ru/lang.php b/platform/www/lib/plugins/tag/lang/ru/lang.php
new file mode 100644
index 0000000..37178e6
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/ru/lang.php
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Aleksandr Selivanov <alexgearbox@yandex.ru>
+ * @author Vasilyy Balyasnyy <v.balyasnyy@gmail.com>
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['tag'] = 'Тег';
+$lang['tags'] = 'Теги';
+$lang['topic'] = 'Темы';
+$lang['count'] = 'Количество';
+$lang['toolbar_icon'] = 'Вставить тег-синтаксис';
+$lang['empty_output'] = 'Пустой вывод';
+
+$lang['include'] = 'Включать';
+$lang['exclude'] = 'Исключать';
+$lang['use_and'] = 'Использовать логическое AND';
+$lang['no_tags'] = 'Теги не найдены';
diff --git a/platform/www/lib/plugins/tag/lang/ru/settings.php b/platform/www/lib/plugins/tag/lang/ru/settings.php
new file mode 100644
index 0000000..b2d38b0
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/ru/settings.php
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Aleksandr Selivanov <alexgearbox@yandex.ru>
+ * @author Vasilyy Balyasnyy <v.balyasnyy@gmail.com>
+ */
+
+$lang['namespace'] = 'Пространство имён по умолчанию для тегов';
+$lang['toolbar_icon'] = 'Показывать кнопку на панели инструментов (если значок не отображается, очистите data/cache/* и кэш браузера)';
+
+$lang['sortkey'] = 'Сортировать список страниц по:';
+$lang['sortkey_o_cdate'] = 'дате создания';
+$lang['sortkey_o_mdate'] = 'дате редактирования';
+$lang['sortkey_o_pagename'] = 'имени страницы';
+$lang['sortkey_o_id'] = 'ID страницы';
+$lang['sortkey_o_ns'] = 'пространству имён';
+$lang['sortkey_o_title'] = 'заголовку';
+
+$lang['sortorder'] = 'Порядок сортировки';
+$lang['sortorder_o_ascending'] = 'по возрастанию';
+$lang['sortorder_o_descending'] = 'по убыванию';
+
+$lang['pagelist_flags'] = 'Признаки (flags) форматирования для списка тегов (разделяйте запятыми; список доступных признаков (flags) описан в документации плагина Pagelist)';
+
+$lang['list_tags_of_subns'] = 'Также показывать теги в подпространствах имён отмеченных пространств имён (синтаксис подсчёта (count))';
+
+$lang['tags_list_css'] = 'Выбрать стиль для списка тегов на страницах';
+$lang['tags_list_css_o_tags'] = 'стиль по умолчанию';
+$lang['tags_list_css_o_tagstop'] = 'оптимизация для размещения наверху страницы';
diff --git a/platform/www/lib/plugins/tag/lang/sv/lang.php b/platform/www/lib/plugins/tag/lang/sv/lang.php
new file mode 100644
index 0000000..ecdc545
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/sv/lang.php
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author hib <hibratt@gmail.com>
+ * @author Tor Härnqvist <tor@harnqvist.se>
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['tag'] = 'Tagg';
+$lang['tags'] = 'Taggar';
+$lang['topic'] = 'Ämne';
+$lang['count'] = 'Antal';
+$lang['toolbar_icon'] = 'Skriv tagg-syntax';
+$lang['empty_output'] = 'Tom utdata';
+
+$lang['include'] = 'Inkludera';
+$lang['exclude'] = 'Exkludera';
+$lang['use_and'] = 'Använd logik AND';
+$lang['no_tags'] = 'Det finns inga taggar';
diff --git a/platform/www/lib/plugins/tag/lang/sv/settings.php b/platform/www/lib/plugins/tag/lang/sv/settings.php
new file mode 100644
index 0000000..b2e15b8
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/sv/settings.php
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author hib <hibratt@gmail.com>
+ * @author Tor Härnqvist <tor@harnqvist.se>
+ */
+
+$lang['namespace'] = 'Standard namespace för taggar';
+$lang['toolbar_icon'] = 'Via verktygsmenyn (tom data/cache/* och webbläsarens cache om den inte visas)';
+
+$lang['sortkey'] = 'sortera ämnen på';
+$lang['sortkey_o_cdate'] = 'skapandedatum';
+$lang['sortkey_o_mdate'] = 'ändringsdatum';
+$lang['sortkey_o_pagename'] = 'sidnamn';
+$lang['sortkey_o_id'] = 'sid-ID';
+$lang['sortkey_o_ns'] = 'namnrymd';
+$lang['sortkey_o_title'] = 'rubrik';
+
+$lang['sortorder'] = 'sorteringsordning';
+$lang['sortorder_o_ascending'] = 'stigande';
+$lang['sortorder_o_descending'] = 'fallande';
+
+$lang['pagelist_flags'] = 'Formatera flaggor för tagglistan (kommaseparerad, för tillgängliga flaggor, se dokumentationen för pagelist plugin) ';
+
+$lang['list_tags_of_subns'] = 'Lista också taggar i sub-namnrymder inom specificerad namnrymd (count syntax)';
+
+$lang['tags_list_css'] = 'Välj stil att applicera sidornas tagglista';
+$lang['tags_list_css_o_tags'] = 'Standardstil';
+$lang['tags_list_css_o_tagstop'] = 'optimerad för tagglista överst på sidan';
diff --git a/platform/www/lib/plugins/tag/lang/tr/lang.php b/platform/www/lib/plugins/tag/lang/tr/lang.php
new file mode 100644
index 0000000..2abcdaf
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/tr/lang.php
@@ -0,0 +1,19 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author İlker R. Kapaç <irifat@gmail.com>
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['tag'] = 'Etiket';
+$lang['tags'] = 'Etiketler';
+$lang['topic'] = 'Başlık';
+$lang['count'] = 'Miktar';
+$lang['toolbar_icon'] = 'Etiket ekle';
+$lang['empty_output'] = 'Çıktıyı temizle';
+
+$lang['include'] = 'Dahil et';
+$lang['exclude'] = 'Hariç tut';
+$lang['use_and'] = 'Mantık kullan AND';
+$lang['no_tags'] = 'Hiç etiket bulunamadı';
diff --git a/platform/www/lib/plugins/tag/lang/tr/settings.php b/platform/www/lib/plugins/tag/lang/tr/settings.php
new file mode 100644
index 0000000..f2b5914
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/tr/settings.php
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author İlker R. Kapaç <irifat@gmail.com>
+ */
+
+$lang['namespace'] = 'Etiketler için varsayılan isim alanı (namespace)';
+$lang['toolbar_icon'] = 'Araç çubuğu simgesini göster (Eğer görünmezse data/cache/ klasörünü ve internet gezgini ara belleğini silin)';
+
+$lang['sortkey'] = 'konu listesinin sıralanış şekli';
+$lang['sortkey_o_cdate'] = 'oluşturulma tarihi';
+$lang['sortkey_o_mdate'] = 'değiştirilme tarihi';
+$lang['sortkey_o_pagename'] = 'sayfa adı';
+$lang['sortkey_o_id'] = 'sayfa kimliği (ID)';
+$lang['sortkey_o_ns'] = 'isim alanı (namespace)';
+$lang['sortkey_o_title'] = 'başlık';
+
+$lang['sortorder'] = 'sıralama şekli';
+$lang['sortorder_o_ascending'] = 'artan';
+$lang['sortorder_o_descending'] = 'azalan';
+
+$lang['pagelist_flags'] = 'Etiket listesi için biçimlendirme bayrakları (flags) (Virgül ile ayrılmış olarak yazın. Kullanılabilir bayrak listesi için pagelist eklentisinin belgelerine bakın)';
+
+$lang['list_tags_of_subns'] = 'Tanımlanan isim alanının altındaki isim alanlarını da listele (sözdizimini say)';
+
+$lang['tags_list_css'] = 'Sayfalardaki etiket listesine uygulanacak biçimlendirmeyi seçin';
+$lang['tags_list_css_o_tags'] = 'Varsayılan biçim';
+$lang['tags_list_css_o_tagstop'] = 'Sayfanın üst tarafında etiket listesi göstermek için uygun';
diff --git a/platform/www/lib/plugins/tag/lang/uk/lang.php b/platform/www/lib/plugins/tag/lang/uk/lang.php
new file mode 100644
index 0000000..9b4680a
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/uk/lang.php
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['tag'] = 'Тег';
+$lang['tags'] = 'Теги';
+$lang['topic'] = 'Тема';
+$lang['count'] = 'Кількість';
+$lang['toolbar_icon'] = 'Вставити синтаксис тегів';
+$lang['empty_output'] = 'Порожній вихід';
+
+$lang['include'] = 'Включити';
+$lang['exclude'] = 'Виключити';
+$lang['use_and'] = 'Використовувати логіку І';
+$lang['no_tags'] = 'Тегів не знайдено';
diff --git a/platform/www/lib/plugins/tag/lang/uk/settings.php b/platform/www/lib/plugins/tag/lang/uk/settings.php
new file mode 100644
index 0000000..2b7c7ab
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/uk/settings.php
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['namespace'] = 'Простір імен за замовчуванням для тегів';
+$lang['toolbar_icon'] = 'Показувати кнопку на панелі інструментів (якщо значок не відображається, очистіть data/cache/* і кеш браузера)';
+
+$lang['sortkey'] = 'Сортувати список сторінок по:';
+$lang['sortkey_o_cdate'] = 'датою створення';
+$lang['sortkey_o_mdate'] = 'датою редагування';
+$lang['sortkey_o_pagename'] = 'імені сторінки';
+$lang['sortkey_o_id'] = 'ID сторінки';
+$lang['sortkey_o_ns'] = 'простору імен';
+$lang['sortkey_o_title'] = 'заголовку';
+
+$lang['sortorder'] = 'Порядок сортування';
+$lang['sortorder_o_ascending'] = 'по зростанню';
+$lang['sortorder_o_descending'] = 'по спаданню';
+
+$lang['pagelist_flags'] = 'Ознаки (flags) форматування для списку тегів (розділяйте комами; список доступних ознак (flags) описаний в документації плагіна Pagelist)';
+
+$lang['list_tags_of_subns'] = 'Також показувати теги в підпросторах імен зазначених просторів імен (синтаксис підрахунку (count))';
+
+$lang['tags_list_css'] = 'Вибрати стиль для списку тегів на сторінках';
+$lang['tags_list_css_o_tags'] = 'стиль за замовчуванням';
+$lang['tags_list_css_o_tagstop'] = 'оптимізація для розміщення нагорі сторінки';
diff --git a/platform/www/lib/plugins/tag/lang/vi/lang.php b/platform/www/lib/plugins/tag/lang/vi/lang.php
new file mode 100644
index 0000000..e038593
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/vi/lang.php
@@ -0,0 +1,19 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Thien Hau <thienhau.9a14@gmail.com>
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['tag'] = 'Thẻ';
+$lang['tags'] = 'Thẻ';
+$lang['topic'] = 'Đề tài';
+$lang['count'] = 'Định lượng';
+$lang['toolbar_icon'] = 'Chèn cú pháp thẻ';
+$lang['empty_output'] = 'Đầu ra trống';
+
+$lang['include'] = 'Bao gồm';
+$lang['exclude'] = 'Loại trừ';
+$lang['use_and'] = 'Dụng logic AND';
+$lang['no_tags'] = 'Không tìm thấy thẻ';
diff --git a/platform/www/lib/plugins/tag/lang/vi/settings.php b/platform/www/lib/plugins/tag/lang/vi/settings.php
new file mode 100644
index 0000000..11d22c2
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/vi/settings.php
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Thien Hau <thienhau.9a14@gmail.com>
+ */
+
+$lang['namespace'] = 'Không gian tên mặc định cho thẻ';
+$lang['toolbar_icon'] = 'Hiện biểu tượng thanh công cụ (xóa data/cache/* và bộ đệm của trình duyệt nếu nó không hiện)';
+
+$lang['sortkey'] = 'sắp xếp danh sách đề tài theo';
+$lang['sortkey_o_cdate'] = 'ngày tạo';
+$lang['sortkey_o_mdate'] = 'ngày sửa đổi';
+$lang['sortkey_o_pagename'] = 'tên trang';
+$lang['sortkey_o_id'] = 'ID trang';
+$lang['sortkey_o_ns'] = 'không gian tên';
+$lang['sortkey_o_title'] = 'tiêu đề';
+
+$lang['sortorder'] = 'thứ tự sắp xếp';
+$lang['sortorder_o_ascending'] = 'tăng dần';
+$lang['sortorder_o_descending'] = 'giảm dần';
+
+$lang['pagelist_flags'] = 'Định dạng cờ cho danh sách thẻ (được phân tách bằng dấu phẩy, để biết các cờ có sẵn, hãy xem tài liệu của Plugin Pagelist)';
+
+$lang['list_tags_of_subns'] = 'Liệt kê thẻ trong các không gian tên con của một không gian tên cụ thể (cú pháp đếm)';
+
+$lang['tags_list_css'] = 'Chọn kiểu áp dụng cho danh sách thẻ của trang';
+$lang['tags_list_css_o_tags'] = 'kiểu mặc định';
+$lang['tags_list_css_o_tagstop'] = 'tối ưu hóa cho danh sách thẻ ở đầu trang';
diff --git a/platform/www/lib/plugins/tag/lang/zh-tw/lang.php b/platform/www/lib/plugins/tag/lang/zh-tw/lang.php
new file mode 100644
index 0000000..7a3db31
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/zh-tw/lang.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * Traditional Chinese language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Danny Lin <danny0838@gmail.com>
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['tag'] = '標籤';
+$lang['tags'] = '標籤';
+$lang['topic'] = '主題';
+$lang['count'] = '數量';
+$lang['toolbar_icon'] = '插入標籤語法';
+$lang['empty_output'] = '清空輸出';
+
+$lang['include'] = '包含';
+$lang['exclude'] = '不含';
+$lang['use_and'] = '使用邏輯AND';
+$lang['no_tags'] = '沒有找到標籤';
diff --git a/platform/www/lib/plugins/tag/lang/zh-tw/settings.php b/platform/www/lib/plugins/tag/lang/zh-tw/settings.php
new file mode 100644
index 0000000..0dedae2
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/zh-tw/settings.php
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * Traditional Chinese language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Danny Lin <danny0838@gmail.com>
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['namespace'] = '標籤預設的命名空間';
+$lang['toolbar_icon'] = '顯示工具列圖示 (如未出現請清除 data/cache/* 及瀏覽器快取)';
+
+$lang['sortkey'] = '主題排序方式';
+$lang['sortkey_o_cdate'] = '建立日期';
+$lang['sortkey_o_mdate'] = '修改日期';
+$lang['sortkey_o_pagename'] = '頁面名稱';
+$lang['sortkey_o_id'] = '頁面全名';
+$lang['sortkey_o_ns'] = '命名空間';
+$lang['sortkey_o_title'] = '頁面標題';
+
+$lang['sortorder'] = '排序方式';
+$lang['sortorder_o_ascending'] = '升序';
+$lang['sortorder_o_descending'] = '降序';
+
+$lang['pagelist_flags'] = '標籤列表的格式化參數 (逗號分隔,可用參數詳見 pagelist 附加元件的說明文件)';
+
+$lang['list_tags_of_subns'] = '也將指定命名空間之下子命名空間中的標籤列出 (count 語法)';
+
+$lang['tags_list_css'] = '選擇應用於頁面標籤列表的樣式';
+$lang['tags_list_css_o_tags'] = '默認樣式';
+$lang['tags_list_css_o_tagstop'] = '針對頁面頂部的標籤列表進行了優化';
diff --git a/platform/www/lib/plugins/tag/lang/zh/lang.php b/platform/www/lib/plugins/tag/lang/zh/lang.php
new file mode 100644
index 0000000..85b29a1
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/zh/lang.php
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author haobug <qingxianhao@gmail.com>
+ * @author Maie <m@maie.name>
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['tag'] = '标签';
+$lang['tags'] = '标签';
+$lang['topic'] = '主题';
+$lang['count'] = '数量';
+$lang['toolbar_icon'] = '插入标签';
+$lang['empty_output'] = '输出为空';
+
+$lang['include'] = '包括';
+$lang['exclude'] = '排除';
+$lang['use_and'] = '使用逻辑AND';
+$lang['no_tags'] = '没有找到标签';
diff --git a/platform/www/lib/plugins/tag/lang/zh/settings.php b/platform/www/lib/plugins/tag/lang/zh/settings.php
new file mode 100644
index 0000000..1d2e9cf
--- /dev/null
+++ b/platform/www/lib/plugins/tag/lang/zh/settings.php
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author haobug <qingxianhao@gmail.com>
+ * @author Maie <m@maie.name>
+ */
+
+$lang['namespace'] = '标签的默认命名空间';
+$lang['toolbar_icon'] = '显示工具栏图标 (如果没有显示,请清除 data/cache/* 及浏览器缓存)';
+
+$lang['sortkey'] = '按何键值排序';
+$lang['sortkey_o_cdate'] = '创建日期';
+$lang['sortkey_o_mdate'] = '修改日期';
+$lang['sortkey_o_pagename'] = '页面名称';
+$lang['sortkey_o_id'] = '页面 ID';
+$lang['sortkey_o_ns'] = '命名空间';
+$lang['sortkey_o_title'] = '页面标题';
+
+$lang['sortorder'] = '排序方式';
+$lang['sortorder_o_ascending'] = '升序';
+$lang['sortorder_o_descending'] = '降序';
+
+$lang['pagelist_flags'] = '标签列表的格式化标志 (逗号分隔,支持标志参考 Pagelist 插件的文档)';
+
+$lang['list_tags_of_subns'] = '列出指定命名空间的子命名空间的标签 (count 语法)';
+
+$lang['tags_list_css'] = '选择用于网页的标签列表样式';
+$lang['tags_list_css_o_tags'] = '默认样式';
+$lang['tags_list_css_o_tagstop'] = '优化在页面顶部显示的标签列表';
diff --git a/platform/www/lib/plugins/tag/manager.dat b/platform/www/lib/plugins/tag/manager.dat
new file mode 100644
index 0000000..1c0d878
--- /dev/null
+++ b/platform/www/lib/plugins/tag/manager.dat
@@ -0,0 +1,2 @@
+downloadurl=https://github.com/dokufreaks/plugin-tag/tarball/master
+installed=Wed, 16 Mar 2022 22:24:26 +0000
diff --git a/platform/www/lib/plugins/tag/plugin.info.txt b/platform/www/lib/plugins/tag/plugin.info.txt
new file mode 100644
index 0000000..4dd666c
--- /dev/null
+++ b/platform/www/lib/plugins/tag/plugin.info.txt
@@ -0,0 +1,7 @@
+base tag
+author Michael Hamann, Gina Häussge, Christopher Smith, Michael Klier, Esther Brunner
+email michael@content-space.de
+date 2020-12-02
+name Tag Plugin
+desc tag wiki pages
+url https://www.dokuwiki.org/plugin:tag
diff --git a/platform/www/lib/plugins/tag/script.js b/platform/www/lib/plugins/tag/script.js
new file mode 100644
index 0000000..ffa1d45
--- /dev/null
+++ b/platform/www/lib/plugins/tag/script.js
@@ -0,0 +1,16 @@
+/**
+ * For the searchtags syntax: make the checkboxes behave like radio buttons
+ * so the user can't both include and exclude a tag
+ */
+jQuery(function() {
+ jQuery('form.plugin__tag_search table input').change(function() {
+ if (jQuery(this).attr('checked')) { // was this input checked?
+ if (jQuery(this).parent().hasClass('minus')) {
+ // find the other input in the same tr and uncheck it
+ jQuery(this).closest('tr').find('.plus input').attr('checked', false);
+ } else {
+ jQuery(this).closest('tr').find('.minus input').attr('checked', false);
+ }
+ }
+ })
+});
diff --git a/platform/www/lib/plugins/tag/style.css b/platform/www/lib/plugins/tag/style.css
new file mode 100644
index 0000000..39b7f1a
--- /dev/null
+++ b/platform/www/lib/plugins/tag/style.css
@@ -0,0 +1,28 @@
+div.dokuwiki div.tags,
+div.dokuwiki div.tagstop {
+ font-size: 95%;
+ text-align: right;
+}
+
+div.dokuwiki div.tags {
+ border-top: 2px dotted __border__;
+ clear: both;
+ margin-bottom: 1.4em;
+}
+
+div.dokuwiki div.tagstop {
+ border-bottom: 2px dotted __border__;
+ margin-top: -1.3em;
+ margin-bottom: .4em;
+}
+
+div.dokuwiki div.tags span,
+div.dokuwiki div.tagstop span {
+ background: transparent url(images/tag.gif) 0px 2px no-repeat;
+ padding: 1px 0px 1px 17px;
+}
+
+/* make it easier to select the +/- checkboxes in the tagsearch table by making them block elements */
+div.dokuwiki form.plugin__tag_search label.plus, div.dokuwiki form.plugin__tag_search label.minus {
+ display: block;
+}
diff --git a/platform/www/lib/plugins/tag/syntax/count.php b/platform/www/lib/plugins/tag/syntax/count.php
new file mode 100644
index 0000000..f19d342
--- /dev/null
+++ b/platform/www/lib/plugins/tag/syntax/count.php
@@ -0,0 +1,124 @@
+<?php
+/**
+ * Tag Plugin: displays list of keywords with links to categories this page
+ * belongs to. The links are marked as tags for Technorati and other services
+ * using tagging.
+ *
+ * Usage: {{tag>category tags space separated}}
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Matthias Schulte <dokuwiki@lupo49.de>
+ */
+
+/** Count syntax, allows to list tag counts */
+class syntax_plugin_tag_count extends DokuWiki_Syntax_Plugin {
+
+ /**
+ * @return string Syntax type
+ */
+ function getType() { return 'substition'; }
+ /**
+ * @return int Sort order
+ */
+ function getSort() { return 305; }
+ /**
+ * @return string Paragraph type
+ */
+ function getPType() { return 'block';}
+
+ /**
+ * @param string $mode Parser mode
+ */
+ function connectTo($mode) {
+ $this->Lexer->addSpecialPattern('\{\{count>.*?\}\}', $mode, 'plugin_tag_count');
+ }
+
+ /**
+ * Handle matches of the count syntax
+ *
+ * @param string $match The match of the syntax
+ * @param int $state The state of the handler
+ * @param int $pos The position in the document
+ * @param Doku_Handler $handler The handler
+ * @return array Data for the renderer
+ */
+ function handle($match, $state, $pos, Doku_Handler $handler) {
+
+ $dump = trim(substr($match, 8, -2)); // get given tags
+ $dump = explode('&', $dump); // split to tags and allowed namespaces
+ $tags = $dump[0];
+ $allowedNamespaces = explode(' ', $dump[1]); // split given namespaces into an array
+
+ if($allowedNamespaces && $allowedNamespaces[0] == '') {
+ unset($allowedNamespaces[0]); // When exists, remove leading space after the delimiter
+ $allowedNamespaces = array_values($allowedNamespaces);
+ }
+
+ if (empty($allowedNamespaces)) $allowedNamespaces = null;
+
+ if (!$tags) $tags = '+';
+
+ /** @var helper_plugin_tag $my */
+ if(!($my = $this->loadHelper('tag'))) return false;
+
+ return array($my->_parseTagList($tags), $allowedNamespaces);
+ }
+
+ /**
+ * Render xhtml output or metadata
+ *
+ * @param string $mode Renderer mode (supported modes: xhtml and metadata)
+ * @param Doku_Renderer $renderer The renderer
+ * @param array $data The data from the handler function
+ * @return bool If rendering was successful.
+ */
+ function render($mode, Doku_Renderer $renderer, $data) {
+ if ($data == false) return false;
+
+ list($tags, $allowedNamespaces) = $data;
+
+ // deactivate (renderer) cache as long as there is no proper cache handling
+ // implemented for the count syntax
+ $renderer->nocache();
+
+ if($mode == "xhtml") {
+ /** @var helper_plugin_tag $my */
+ if(!($my = $this->loadHelper('tag'))) return false;
+
+ // get tags and their occurrences
+ if($tags[0] == '+') {
+ // no tags given, list all tags for allowed namespaces
+ $occurrences = $my->tagOccurrences($tags, $allowedNamespaces, true);
+ } else {
+ $occurrences = $my->tagOccurrences($tags, $allowedNamespaces);
+ }
+
+ $class = "inline"; // valid: inline, ul, pagelist
+ $col = "page";
+
+ $renderer->doc .= '<table class="'.$class.'">'.DOKU_LF;
+ $renderer->doc .= DOKU_TAB.'<tr>'.DOKU_LF.DOKU_TAB.DOKU_TAB;
+ $renderer->doc .= '<th class="'.$col.'">'.$this->getLang('tag').'</th>';
+ $renderer->doc .= '<th class="'.$col.'">'.$this->getLang('count').'</th>';
+ $renderer->doc .= DOKU_LF.DOKU_TAB.'</tr>'.DOKU_LF;
+
+ if(empty($occurrences)) {
+ // Skip output
+ $renderer->doc .= DOKU_TAB.'<tr>'.DOKU_LF.DOKU_TAB.DOKU_TAB;
+ $renderer->doc .= DOKU_TAB.DOKU_TAB.'<td class="'.$class.'" colspan="2">'.$this->getLang('empty_output').'</td>'.DOKU_LF;
+ $renderer->doc .= DOKU_LF.DOKU_TAB.'</tr>'.DOKU_LF;
+ } else {
+ foreach($occurrences as $tagname => $count) {
+ if($count <= 0) continue; // don't display tags with zero occurrences
+ $renderer->doc .= DOKU_TAB.'<tr>'.DOKU_LF.DOKU_TAB.DOKU_TAB;
+ $renderer->doc .= DOKU_TAB.DOKU_TAB.'<td class="'.$class.'">'.$my->tagLink($tagname).'</td>'.DOKU_LF;
+ $renderer->doc .= DOKU_TAB.DOKU_TAB.'<td class="'.$class.'">'.$count.'</td>'.DOKU_LF;
+ $renderer->doc .= DOKU_LF.DOKU_TAB.'</tr>'.DOKU_LF;
+ }
+ }
+ $renderer->doc .= '</table>'.DOKU_LF;
+ }
+ return true;
+ }
+}
+// vim:ts=4:sw=4:et:
diff --git a/platform/www/lib/plugins/tag/syntax/searchtags.php b/platform/www/lib/plugins/tag/syntax/searchtags.php
new file mode 100644
index 0000000..67d62b3
--- /dev/null
+++ b/platform/www/lib/plugins/tag/syntax/searchtags.php
@@ -0,0 +1,281 @@
+<?php
+/**
+ * Syntax plugin part for displaying a tag search form with results.
+ *
+ * Usage: {{tagsearch[&flags]}}
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Michael Hamann <michael@content-space.de>
+ */
+
+/**
+ * Tagsearch syntax, displays a tag search form with results similar to the topic syntax
+ */
+class syntax_plugin_tag_searchtags extends DokuWiki_Syntax_Plugin {
+ /**
+ * @return string Syntax type
+ */
+ function getType() { return 'substition'; }
+
+ /**
+ * @return string Paragraph type
+ */
+ function getPType() { return 'block'; }
+
+ /**
+ * @return int Sort order
+ */
+ function getSort() { return 295; }
+
+ /**
+ * @param string $mode Parser mode
+ */
+ function connectTo($mode) {
+ $this->Lexer->addSpecialPattern('\{\{searchtags\}\}',$mode,'plugin_tag_searchtags');
+ // make sure that flags really start with & and media files starting with "searchtags" still work
+ $this->Lexer->addSpecialPattern('\{\{searchtags&.*?\}\}',$mode,'plugin_tag_searchtags');
+ }
+
+ /**
+ * Handle matches of the searchtags syntax
+ *
+ * @param string $match The match of the syntax
+ * @param int $state The state of the handler
+ * @param int $pos The position in the document
+ * @param Doku_Handler $handler The handler
+ * @return array Data for the renderer
+ */
+ function handle($match, $state, $pos, Doku_Handler $handler) {
+ $flags = substr($match, 10, -2); // strip {{searchtags from start and }} from end
+ // remove empty flags by using array_filter (removes elements == false)
+ $flags = array_filter(explode('&', $flags));
+
+ return $flags;
+ }
+
+ /**
+ * Render xhtml output or metadata
+ *
+ * @param string $mode Renderer mode (supported modes: xhtml and metadata)
+ * @param Doku_Renderer $renderer The renderer
+ * @param array $data The data from the handler function
+ * @return bool If rendering was successful.
+ */
+ function render($mode, Doku_Renderer $renderer, $data) {
+ global $lang;
+ $flags = $data;
+
+ if ($mode == 'xhtml') {
+ /* @var Doku_Renderer_xhtml $renderer */
+
+ // prevent caching to ensure content is always fresh
+ $renderer->nocache();
+
+ /* @var helper_plugin_pagelist $pagelist */
+ // let Pagelist Plugin do the work for us
+ if ((!$pagelist = $this->loadHelper('pagelist'))) {
+ return false;
+ }
+
+ // Prepare the flags for the pagelist plugin
+ $configflags = explode(',', str_replace(" ", "", $this->getConf('pagelist_flags')));
+ $flags = array_merge($configflags, $flags);
+ foreach($flags as $key => $flag) {
+ if($flag == "") unset($flags[$key]);
+ }
+
+ // print the search form
+ $nonsform = in_array('nonsform', $flags);
+ $renderer->doc .= $this->getForm($nonsform);
+
+ // get the tag input data
+ $tags = $this->getTagSearchString();
+
+ if ($tags != NULL) {
+ /* @var helper_plugin_tag $my */
+ if ($my = $this->loadHelper('tag')) $pages = $my->getTopic($this->getNS(), '', $tags);
+
+ // Display a message when no pages were found
+ if (!isset($pages) || !$pages) {
+ $renderer->p_open();
+ $renderer->cdata($lang['nothingfound']);
+ $renderer->p_close();
+ } else {
+
+ // display the actual search results
+ $pagelist->setFlags($flags);
+ $pagelist->startList();
+ foreach ($pages as $page) {
+ $pagelist->addPage($page);
+ }
+ $renderer->doc .= $pagelist->finishList();
+ }
+ }
+
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Return the search form for the namespace and the tag selection
+ *
+ * @return string the HTML code of the search form
+ */
+ private function getForm($nonsform=false) {
+ global $conf, $lang;
+
+ if (!$nonsform) {
+ // Get the list of all namespaces for the dropdown
+ $namespaces = array();
+ search($namespaces,$conf['datadir'],'search_namespaces',array());
+
+ // build the list in the form value => label from the namespace search result
+ $ns_select = array('' => '');
+ foreach ($namespaces as $ns) {
+ // only display namespaces the user can access when sneaky index is on
+ if ($ns['perm'] > 0 || $conf['sneaky_index'] == 0) {
+ $ns_select[$ns['id']] = $ns['id'];
+ }
+ }
+ }
+
+ $form = new Doku_Form(array('action' => '', 'method' => 'post', 'class' => 'plugin__tag_search'));
+
+ // add a paragraph around the inputs in order to get some margin around the form elements
+ $form->addElement(form_makeOpenTag('p'));
+ // namespace select
+ if (!$nonsform) {
+ $form->addElement(form_makeMenuField('plugin__tag_search_namespace', $ns_select, $this->getNS(), $lang['namespaces']));
+ }
+
+ // checkbox for AND
+ $attr = array();
+ if ($this->useAnd()) $attr['checked'] = 'checked';
+ $form->addElement(form_makeCheckboxField('plugin__tag_search_and', 1, $this->getLang('use_and'), '', '', $attr));
+ $form->addElement(form_makeCloseTag('p'));
+
+ // load the tag list - only tags that actually have pages assigned that the current user can access are listed
+ /* @var helper_plugin_tag $my */
+ if ($my = $this->loadHelper('tag')) $tags = $my->tagOccurrences(array(), NULL, true);
+ // sort tags by name ($tags is in the form $tag => $count)
+ ksort($tags);
+
+ // display error message when no tags were found
+ if (!isset($tags) || $tags == NULL) {
+ $form->addElement(form_makeOpenTag('p'));
+ $form->addElement($this->getLang('no_tags'));
+ $form->addElement(form_makeCloseTag('p'));
+ } else {
+ // the tags table
+ $form->addElement(form_makeOpenTag('div', array('class' => 'table')));
+ $form->addElement(form_makeOpenTag('table', array('class' => 'inline')));
+ // print table header
+ $form->addElement(form_makeOpenTag('tr'));
+ $form->addElement(form_makeOpenTag('th'));
+ $form->addElement($this->getLang('include'));
+ $form->addElement(form_makeCloseTag('th'));
+ $form->addElement(form_makeOpenTag('th'));
+ $form->addElement($this->getLang('exclude'));
+ $form->addElement(form_makeCloseTag('th'));
+ $form->addElement(form_makeOpenTag('th'));
+ $form->addElement($this->getLang('tags'));
+ $form->addElement(form_makeCloseTag('th'));
+ $form->addElement(form_makeCloseTag('tr'));
+
+ // print tag checkboxes
+ foreach ($tags as $tag => $count) {
+ $form->addElement(form_makeOpenTag('tr'));
+ $form->addElement(form_makeOpenTag('td'));
+ $attr = array();
+ if ($this->isSelected($tag)) $attr['checked'] = 'checked';
+ $form->addElement(form_makeCheckboxField('plugin__tag_search_tags[]', $tag, '+', '', 'plus', $attr));
+ $form->addElement(form_makeCloseTag('td'));
+ $form->addElement(form_makeOpenTag('td'));
+ $attr = array();
+ if ($this->isSelected('-'.$tag)) $attr['checked'] = 'checked';
+ $form->addElement(form_makeCheckboxField('plugin__tag_search_tags[]', '-'.$tag, '-', '', 'minus', $attr));
+ $form->addElement(form_makeCloseTag('td'));
+ $form->addElement(form_makeOpenTag('td'));
+ $form->addElement(hsc($tag).' ['.$count.']');
+ $form->addElement(form_makeCloseTag('td'));
+ $form->addElement(form_makeCloseTag('tr'));
+ }
+
+ $form->addElement(form_makeCloseTag('table'));
+ $form->addElement(form_makeCloseTag('div'));
+
+ // submit button (doesn't use the button form element because it always submits an action which is not
+ // recognized for $preact in inc/actions.php and thus always causes a redirect)
+ $form->addElement(form_makeOpenTag('p'));
+ $form->addElement(form_makeTag('input', array('type' => 'submit', 'value' => $lang['btn_search'])));
+ $form->addElement(form_makeCloseTag('p'));
+ }
+
+ return $form->getForm();
+ }
+
+ /**
+ * Returns the currently selected namespace
+ * @return string the cleaned namespace id
+ */
+ private function getNS() {
+ if (isset($_POST['plugin__tag_search_namespace'])) {
+ return cleanID($_POST['plugin__tag_search_namespace']);
+ } else {
+ return '';
+ }
+ }
+
+ /**
+ * Returns the tag search string from the selected tags
+ * @return string|NULL the tag search or NULL when no tags were selected
+ */
+ private function getTagSearchString() {
+ if (isset($_POST['plugin__tag_search_tags']) && is_array($_POST['plugin__tag_search_tags'])) {
+ $tags = $_POST['plugin__tag_search_tags'];
+ // wWhen and is set, prepend "+" to each tag
+ $plus = (isset($_POST['plugin__tag_search_and']) ? '+' : '');
+ $positive_tags = '';
+ $negative_tags = '';
+ foreach ($tags as $tag) {
+ $tag = (string)$tag;
+ if ($tag[0] == '-') {
+ $negative_tags .= $tag.' ';
+ } else {
+ if ($positive_tags === '') {
+ $positive_tags = $tag.' ';
+ } else {
+ $positive_tags .= $plus.$tag.' ';
+ }
+ }
+ }
+ return $positive_tags.$negative_tags;
+ } else {
+ return NULL; // return NULL when no tags were selected so no results will be displayed
+ }
+ }
+
+ /**
+ * Check if a tag was selected for search
+ *
+ * @param string $tag The tag to check
+ * @return bool if the tag was checked
+ */
+ private function isSelected($tag) {
+ if (isset($_POST['plugin__tag_search_tags']) && is_array($_POST['plugin__tag_search_tags'])) {
+ return in_array($tag, $_POST['plugin__tag_search_tags'], true);
+ } else {
+ return false; // no tags in the post data - no tag selected
+ }
+ }
+
+ /**
+ * Check if the tag query should use AND (instead of OR)
+ *
+ * @return bool if the query should use AND
+ */
+ private function useAnd() {
+ return isset($_POST['plugin__tag_search_and']);
+ }
+}
+// vim:ts=4:sw=4:et:
diff --git a/platform/www/lib/plugins/tag/syntax/tag.php b/platform/www/lib/plugins/tag/syntax/tag.php
new file mode 100644
index 0000000..dc8bce5
--- /dev/null
+++ b/platform/www/lib/plugins/tag/syntax/tag.php
@@ -0,0 +1,112 @@
+<?php
+/**
+ * Tag Plugin: displays list of keywords with links to categories this page
+ * belongs to. The links are marked as tags for Technorati and other services
+ * using tagging.
+ *
+ * Usage: {{tag>category tags space separated}}
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Esther Brunner <wikidesign@gmail.com>
+ */
+
+/**
+ * Tag syntax plugin, allows to specify tags in a page
+ */
+class syntax_plugin_tag_tag extends DokuWiki_Syntax_Plugin {
+
+ /**
+ * @return string Syntax type
+ */
+ function getType() { return 'substition'; }
+ /**
+ * @return int Sort order
+ */
+ function getSort() { return 305; }
+ /**
+ * @return string Paragraph type
+ */
+ function getPType() { return 'block';}
+
+ /**
+ * @param string $mode Parser mode
+ */
+ function connectTo($mode) {
+ $this->Lexer->addSpecialPattern('\{\{tag>.*?\}\}', $mode, 'plugin_tag_tag');
+ }
+
+ /**
+ * Handle matches of the tag syntax
+ *
+ * @param string $match The match of the syntax
+ * @param int $state The state of the handler
+ * @param int $pos The position in the document
+ * @param Doku_Handler $handler The handler
+ * @return array Data for the renderer
+ */
+ function handle($match, $state, $pos, Doku_Handler $handler) {
+ $tags = trim(substr($match, 6, -2)); // strip markup & whitespace
+ $tags = preg_replace(array('/[[:blank:]]+/', '/\s+/'), " ", $tags); // replace linebreaks and multiple spaces with one space character
+
+ if (!$tags) return false;
+
+ // load the helper_plugin_tag
+ /** @var helper_plugin_tag $my */
+ if (!$my = $this->loadHelper('tag')) return false;
+
+ // split tags and returns for renderer
+ return $my->_parseTagList($tags);
+ }
+
+ /**
+ * Render xhtml output or metadata
+ *
+ * @param string $mode Renderer mode (supported modes: xhtml and metadata)
+ * @param Doku_Renderer $renderer The renderer
+ * @param array $data The data from the handler function
+ * @return bool If rendering was successful.
+ */
+ function render($mode, Doku_Renderer $renderer, $data) {
+ if ($data === false) return false;
+ /** @var helper_plugin_tag $my */
+ if (!$my = $this->loadHelper('tag')) return false;
+
+ // XHTML output
+ if ($mode == 'xhtml') {
+ $tags = $my->tagLinks($data);
+ if (!$tags) return true;
+ $renderer->doc .= '<div class="'.$this->getConf('tags_list_css').'"><span>'.DOKU_LF.
+ DOKU_TAB.$tags.DOKU_LF.
+ '</span></div>'.DOKU_LF;
+ return true;
+
+ // for metadata renderer
+ } elseif ($mode == 'metadata') {
+ /** @var Doku_Renderer_metadata $renderer */
+ // erase tags on persistent metadata no more used
+ if (isset($renderer->persistent['subject'])) {
+ unset($renderer->persistent['subject']);
+ $renderer->meta['subject'] = array();
+ }
+
+ if (!isset($renderer->meta['subject'])) $renderer->meta['subject'] = array();
+
+ // each registered tags in metadata and index should be valid IDs
+ $data = array_map('cleanID', $data);
+ // merge with previous tags and make the values unique
+ $renderer->meta['subject'] = array_unique(array_merge($renderer->meta['subject'], $data));
+
+ if ($renderer->capture) $renderer->doc .= DOKU_LF.implode(' ', $data).DOKU_LF;
+
+ // add references if tag page exists
+ foreach ($data as $tag) {
+ resolve_pageid($my->namespace, $tag, $exists); // resolve shortcuts
+ $renderer->meta['relation']['references'][$tag] = $exists;
+ }
+
+ return true;
+ }
+ return false;
+ }
+}
+// vim:ts=4:sw=4:et:
diff --git a/platform/www/lib/plugins/tag/syntax/tagpage.php b/platform/www/lib/plugins/tag/syntax/tagpage.php
new file mode 100644
index 0000000..bec2e70
--- /dev/null
+++ b/platform/www/lib/plugins/tag/syntax/tagpage.php
@@ -0,0 +1,90 @@
+<?php
+/**
+ * Tag Plugin: Display a link to the listing of all pages with a certain tag.
+ *
+ * Usage: {{tagpage>mytag[&dynamic][|title]}}
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Matthias Schulte <dokuwiki@lupo49.de>
+ */
+
+/** Tagpage syntax, allows to link to a given tag */
+class syntax_plugin_tag_tagpage extends DokuWiki_Syntax_Plugin {
+
+ /**
+ * @return string Syntax type
+ */
+ function getType() {
+ return 'substition';
+ }
+
+ /**
+ * @return int Sort order
+ */
+ function getSort() {
+ return 305;
+ }
+
+ /**
+ * @return string Paragraph type
+ */
+ function getPType() {
+ return 'normal';
+ }
+
+ /**
+ * @param string $mode Parser mode
+ */
+ function connectTo($mode) {
+ $this->Lexer->addSpecialPattern('\{\{tagpage>.*?\}\}', $mode, 'plugin_tag_tagpage');
+ }
+
+ /**
+ * Handle matches of the count syntax
+ *
+ * @param string $match The match of the syntax
+ * @param int $state The state of the handler
+ * @param int $pos The position in the document
+ * @param Doku_Handler $handler The handler
+ * @return array Data for the renderer
+ */
+ function handle($match, $state, $pos, Doku_Handler $handler) {
+ $params = array();
+ $dump = trim(substr($match, 10, -2)); // get given tag
+ $dump = explode('|', $dump, 2); // split to tags, link name and options
+ $params['title'] = $dump[1];
+ $dump = explode('&', $dump[0]);
+ $params['dynamic'] = ($dump[1] == 'dynamic');
+ $params['tag'] = trim($dump[0]);
+
+ return $params;
+ }
+
+ /**
+ * Render xhtml output
+ *
+ * @param string $mode Renderer mode (supported modes: xhtml)
+ * @param Doku_Renderer $renderer The renderer
+ * @param array $data The data from the handler function
+ * @return bool If rendering was successful.
+ */
+ function render($mode, Doku_Renderer $renderer, $data) {
+ if($data == false) return false;
+
+ if($mode == "xhtml") {
+ if($data['dynamic']) {
+ // deactivate (renderer) cache as long as there is no proper cache handling
+ // implemented for the count syntax
+ $renderer->nocache();
+ }
+
+ /** @var helper_plugin_tag $my */
+ if(!($my = $this->loadHelper('tag'))) return false;
+
+ $renderer->doc .= $my->tagLink($data['tag'], $data['title'], $data['dynamic']);
+ return true;
+ }
+ return false;
+ }
+}
+// vim:ts=4:sw=4:et:
diff --git a/platform/www/lib/plugins/tag/syntax/topic.php b/platform/www/lib/plugins/tag/syntax/topic.php
new file mode 100644
index 0000000..a065a94
--- /dev/null
+++ b/platform/www/lib/plugins/tag/syntax/topic.php
@@ -0,0 +1,129 @@
+<?php
+/**
+ * Tag Plugin, topic component: displays links to all wiki pages with a certain tag
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Esther Brunner <wikidesign@gmail.com>
+ */
+
+/**
+ * Topic syntax, displays links to all wiki pages with a certain tag
+ */
+class syntax_plugin_tag_topic extends DokuWiki_Syntax_Plugin {
+
+ /**
+ * @return string Syntax type
+ */
+ function getType() { return 'substition'; }
+
+ /**
+ * @return string Paragraph type
+ */
+ function getPType() { return 'block'; }
+
+ /**
+ * @return int Sort order
+ */
+ function getSort() { return 295; }
+
+ /**
+ * @param string $mode Parser mode
+ */
+ function connectTo($mode) {
+ $this->Lexer->addSpecialPattern('\{\{topic>.+?\}\}',$mode,'plugin_tag_topic');
+ }
+
+ /**
+ * Handle matches of the topic syntax
+ *
+ * @param string $match The match of the syntax
+ * @param int $state The state of the handler
+ * @param int $pos The position in the document
+ * @param Doku_Handler $handler The handler
+ * @return array Data for the renderer
+ */
+ function handle($match, $state, $pos, Doku_Handler $handler) {
+ global $ID;
+
+ $match = substr($match, 8, -2); // strip {{topic> from start and }} from end
+ list($match, $flags) = explode('&', $match, 2);
+ $flags = explode('&', $flags);
+ list($ns, $tag) = explode('?', $match);
+
+ if (!$tag) {
+ $tag = $ns;
+ $ns = '';
+ }
+
+ if (($ns == '*') || ($ns == ':')) $ns = '';
+ elseif ($ns == '.') $ns = getNS($ID);
+ else $ns = cleanID($ns);
+
+ return array($ns, trim($tag), $flags);
+ }
+
+ /**
+ * Render xhtml output or metadata
+ *
+ * @param string $mode Renderer mode (supported modes: xhtml and metadata)
+ * @param Doku_Renderer $renderer The renderer
+ * @param array $data The data from the handler function
+ * @return bool If rendering was successful.
+ */
+ function render($mode, Doku_Renderer $renderer, $data) {
+ list($ns, $tag, $flags) = $data;
+
+ /* @var helper_plugin_tag $my */
+ if ($my = $this->loadHelper('tag')) $pages = $my->getTopic($ns, '', $tag);
+ if (!isset($pages) || !$pages) return true; // nothing to display
+
+ if ($mode == 'xhtml') {
+ /* @var Doku_Renderer_xhtml $renderer */
+
+ // prevent caching to ensure content is always fresh
+ $renderer->nocache();
+
+ /* @var helper_plugin_pagelist $pagelist */
+ // let Pagelist Plugin do the work for us
+ if ((!$pagelist = $this->loadHelper('pagelist'))) {
+ return false;
+ }
+ $pagelist->sort = false;
+ $pagelist->rsort = false;
+
+ $configflags = explode(',', str_replace(" ", "", $this->getConf('pagelist_flags')));
+ $flags = array_merge($configflags, $flags);
+ foreach($flags as $key => $flag) {
+ if($flag == "") unset($flags[$key]);
+ }
+
+ $pagelist->setFlags($flags);
+ $pagelist->startList();
+
+ // Sort pages by pagename if required by flags
+ if($pagelist->sort || $pagelist->rsort) {
+ $keys = array();
+ $fnc = create_function('$a, $b', 'return strcmp(noNS($a["id"]), noNS($b["id"])); ');
+ usort($pages, $fnc);
+ // rsort is true - revserse sort the pages
+ if($pagelist->rsort) krsort($pages);
+ }
+
+ foreach ($pages as $page) {
+ $pagelist->addPage($page);
+ }
+ $renderer->doc .= $pagelist->finishList();
+ return true;
+
+ // for metadata renderer
+/* } elseif ($mode == 'metadata') {
+ foreach ($pages as $page) {
+ $renderer->meta['relation']['references'][$page['id']] = true;
+ }
+
+ return true;*/ // causes issues with backlinks
+ }
+ return false;
+ }
+}
+// vim:ts=4:sw=4:et: