From f31b474e1f720e94b37cfedfe0febe453284f158 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 28 May 2019 17:57:29 +0200 Subject: [news] Modularize; add 'login-news' category TODO: Use date/time picker for expire time --- modules-available/news/api.inc.php | 4 +- modules-available/news/install.inc.php | 16 +- modules-available/news/lang/de/messages.json | 5 +- modules-available/news/lang/de/module.json | 6 +- modules-available/news/lang/de/permissions.json | 10 +- modules-available/news/lang/de/template-tags.json | 17 +- modules-available/news/lang/en/messages.json | 5 +- modules-available/news/lang/en/module.json | 6 +- modules-available/news/lang/en/permissions.json | 10 +- modules-available/news/lang/en/template-tags.json | 17 +- modules-available/news/page.inc.php | 287 +++++++++++---------- .../news/permissions/permissions.json | 6 + modules-available/news/templates/page-news.html | 198 ++++++-------- 13 files changed, 302 insertions(+), 285 deletions(-) diff --git a/modules-available/news/api.inc.php b/modules-available/news/api.inc.php index cbfaa82b..851f31a8 100644 --- a/modules-available/news/api.inc.php +++ b/modules-available/news/api.inc.php @@ -6,7 +6,7 @@ $type = Request::any('type', 'news', 'string'); // Fetch news from DB $row = Database::queryFirst('SELECT title, content, dateline FROM vmchooser_pages' - . ' WHERE type = :type ORDER BY dateline DESC LIMIT 1', compact('type')); + . ' WHERE type = :type AND expires > UNIX_TIMESTAMP() ORDER BY dateline DESC LIMIT 1', compact('type')); if ($row !== false ) { echo '' . "\n"; @@ -15,7 +15,7 @@ if ($row !== false ) { echo "\t\t" . htmlspecialchars($row['title']) . "\n"; echo "\t" . '' . "\n"; echo "\t" . "" . "\n"; - echo "\t\t" . htmlspecialchars(nl2br($row['content'])) . "\n"; + echo "\t\t" . htmlspecialchars($row['content']) . "\n"; echo "\t" . '' . "\n"; echo "\t" . "" . "\n"; echo "\t\t" . $row['dateline'] . "\n"; diff --git a/modules-available/news/install.inc.php b/modules-available/news/install.inc.php index e5e52256..43336290 100644 --- a/modules-available/news/install.inc.php +++ b/modules-available/news/install.inc.php @@ -23,14 +23,26 @@ if (tableExists('news')) { $res[] = tableCreate('vmchooser_pages', " `newsid` int(10) unsigned NOT NULL AUTO_INCREMENT, `dateline` int(10) unsigned NOT NULL, + `expires` int(10) unsigned NOT NULL, `title` varchar(200) DEFAULT NULL, `content` text, `type` varchar(10), PRIMARY KEY (`newsid`), - KEY `type` (`type`, `dateline`) + KEY `type` (`type`, `dateline`), + KEY `all3` (`type`, `expires`, `dateline`) "); -Database::exec('ALTER TABLE vmchooser_pages DROP KEY `dateline`, ADD KEY `type` (`type`, `dateline`)'); +if (tableHasIndex('vmchooser_pages', ['dateline'])) { + Database::exec('ALTER TABLE vmchooser_pages DROP KEY `dateline`'); + Database::exec('ALTER TABLE vmchooser_pages ADD KEY `type` (`type`, `dateline`)'); +} +if (!tableHasIndex('vmchooser_pages', ['type', 'expires', 'dateline'])) { + Database::exec('ALTER TABLE vmchooser_pages ADD KEY `all3` (`type`, `expires`, `dateline`)'); +} +if (!tableHasColumn('vmchooser_pages', 'expires')) { + Database::exec('ALTER TABLE vmchooser_pages ADD COLUMN `expires` int(10) unsigned NOT NULL AFTER `dateline`'); + Database::exec('UPDATE vmchooser_pages SET expires = dateline + 86400 * 3650 WHERE expires = 0'); // ~10 Years +} // Create response for browser diff --git a/modules-available/news/lang/de/messages.json b/modules-available/news/lang/de/messages.json index 248a07fe..b81f6ebd 100644 --- a/modules-available/news/lang/de/messages.json +++ b/modules-available/news/lang/de/messages.json @@ -1,7 +1,8 @@ { - "help-save-success": "Hilfe erfolgreich aktualisiert", "invalid-action": "Ung\u00fcltige Aktion: {{0}}", + "invalid-type": "Ung\u00fcltiger Text-Typ: {{0}}", "news-del-success": "News gel\u00f6scht", "news-empty": "Es wurde keine News in der Datenbank gefunden", - "news-save-success": "News erfolgreich aktualisiert" + "news-save-success": "News erfolgreich aktualisiert", + "save-error": "Fehler beim Speichern" } \ No newline at end of file diff --git a/modules-available/news/lang/de/module.json b/modules-available/news/lang/de/module.json index f44a64e5..4ee68249 100644 --- a/modules-available/news/lang/de/module.json +++ b/modules-available/news/lang/de/module.json @@ -1,3 +1,7 @@ { - "module_name": "vmChooser News" + "module_name": "News-\/Hilfetexte", + "page_title": "Neuigkeiten und Hilfetexte", + "type_help": "vmChooser Hilfe", + "type_login-news": "Loginmaske", + "type_news": "vmChooser News" } \ No newline at end of file diff --git a/modules-available/news/lang/de/permissions.json b/modules-available/news/lang/de/permissions.json index 888bb4a7..04d4a46e 100644 --- a/modules-available/news/lang/de/permissions.json +++ b/modules-available/news/lang/de/permissions.json @@ -1,7 +1,9 @@ { "access-page": "Seite sehen.", - "help.delete": "Alte Hilfe Texte l\u00f6schen.", - "help.save": "\u00c4nderungen am Hilfe Text speichern.", - "news.delete": "Alte News Texte l\u00f6schen.", - "news.save": "\u00c4nderungen am News Text speichern." + "help.delete": "vmChooser Hilfetexte l\u00f6schen.", + "help.save": "Neue vmChooser Hilfetexte speichern.", + "login-news.delete": "News-Texte f\u00fcr den Loginbildschirm l\u00f6schen.", + "login-news.save": "News-Texte f\u00fcr den Loginbildschirm speichern.", + "news.delete": "vmChooser News-Texte l\u00f6schen.", + "news.save": "Neue vmChooser News-Texte speichern." } \ No newline at end of file diff --git a/modules-available/news/lang/de/template-tags.json b/modules-available/news/lang/de/template-tags.json index c2b4bddc..b5c72ff4 100644 --- a/modules-available/news/lang/de/template-tags.json +++ b/modules-available/news/lang/de/template-tags.json @@ -1,14 +1,15 @@ { "lang_confirmDelete": "Eintrag l\u00f6schen?", "lang_content": "Inhalt", - "lang_date": "Datum", - "lang_editHelp": "Hilfe bearbeiten", - "lang_editNews": "News bearbeiten", - "lang_latestUpdate": "Letzte Aktualisierung", - "lang_newsIntro": "Hier haben Sie die M\u00f6glichkeit, die von bwLehrpool-Clients angezeigten News zu editieren.", - "lang_newsOld": "Alte News", - "lang_oldHelp": "Alte Hilfetexte", + "lang_created": "Erstellt", + "lang_expires": "Ablauf", + "lang_introText": "Hier k\u00f6nnen Sie f\u00fcr verschiedene Bereiche des MiniLinux-Systems Neuigkeiten, Hilfetexte etc. definieren.", + "lang_lastUpdate": "Letzte Aktualisierung", + "lang_leaveEmptyInfinite": "0 oder leer bedeutet unendlich", + "lang_mainHeading": "Neuigkeiten und Hilfetexte", + "lang_previousEntries": "Vorherige Eintr\u00e4ge", "lang_show": "Ansehen", "lang_title": "Titel", - "lang_vmChooser_title": "vmChooser-Einstellungen" + "lang_titlePh": "\u00dcberschrift", + "lang_validityHours": "G\u00fcltigkeitsdauer in Stunden" } \ No newline at end of file diff --git a/modules-available/news/lang/en/messages.json b/modules-available/news/lang/en/messages.json index 4eaf4306..c44e0cd0 100644 --- a/modules-available/news/lang/en/messages.json +++ b/modules-available/news/lang/en/messages.json @@ -1,7 +1,8 @@ { - "help-save-success": "Help updated successfully", "invalid-action": "Invalid action: {{0}}", + "invalid-type": "Invalid text type: {{0}}", "news-del-success": "News deleted", "news-empty": "There was no news found in the database", - "news-save-success": "News updated successfully" + "news-save-success": "News updated successfully", + "save-error": "Error saving entry" } \ No newline at end of file diff --git a/modules-available/news/lang/en/module.json b/modules-available/news/lang/en/module.json index f44a64e5..f24c306b 100644 --- a/modules-available/news/lang/en/module.json +++ b/modules-available/news/lang/en/module.json @@ -1,3 +1,7 @@ { - "module_name": "vmChooser News" + "module_name": "vmChooser News", + "page_title": "News and help texts", + "type_help": "vmChooser help", + "type_login-news": "Login screen", + "type_news": "vmChooser news" } \ No newline at end of file diff --git a/modules-available/news/lang/en/permissions.json b/modules-available/news/lang/en/permissions.json index 37fc7a8e..4363943c 100644 --- a/modules-available/news/lang/en/permissions.json +++ b/modules-available/news/lang/en/permissions.json @@ -1,7 +1,9 @@ { "access-page": "View page.", - "help.delete": "Delete old help texts.", - "help.save": "Save new help texts.", - "news.delete": "Delete old news.", - "news.save": "Save new news." + "help.delete": "Delete vmChooser help texts.", + "help.save": "Save new vmChooser help texts.", + "login-news.delete": "Delete login screen help texts.", + "login-news.save": "Save new login screen help texts.", + "news.delete": "Delete vmChooser news.", + "news.save": "Save new vmChooser news." } \ No newline at end of file diff --git a/modules-available/news/lang/en/template-tags.json b/modules-available/news/lang/en/template-tags.json index d7567d99..f901c684 100644 --- a/modules-available/news/lang/en/template-tags.json +++ b/modules-available/news/lang/en/template-tags.json @@ -1,14 +1,15 @@ { "lang_confirmDelete": "Delete entry?", "lang_content": "Content", - "lang_date": "Date", - "lang_editHelp": "Edit Help", - "lang_editNews": "Edit news", - "lang_latestUpdate": "Latest update", - "lang_newsIntro": "Here you have the possibility to edit the news displayed to the bwLehrpool clients.", - "lang_newsOld": "Old News", - "lang_oldHelp": "Old Help Texts", + "lang_created": "Created", + "lang_expires": "Expires", + "lang_introText": "Here you can define news, help and other informational texts to be displayed in different places in the running MiniLinux system.", + "lang_lastUpdate": "Last update", + "lang_leaveEmptyInfinite": "0\/empty means infinite", + "lang_mainHeading": "News and help texts", + "lang_previousEntries": "Previous entries", "lang_show": "Show", "lang_title": "Title", - "lang_vmChooser_title": "vmChooser-Settings" + "lang_titlePh": "Headline for Text", + "lang_validityHours": "Validity in hours" } \ No newline at end of file diff --git a/modules-available/news/page.inc.php b/modules-available/news/page.inc.php index 1e2e3eef..8e2b4e7e 100644 --- a/modules-available/news/page.inc.php +++ b/modules-available/news/page.inc.php @@ -2,6 +2,19 @@ class Page_News extends Page { + + private $hasSummernote = false; + + const TYPES = [ + // Dictionary::translate('type_news'); + 'news' => ['headline' => true], + // Dictionary::translate('type_help'); + 'help' => ['headline' => false], + // Dictionary::translate('type_login-news'); + 'login-news' => ['headline' => false], + ]; + + private $pageType = false; /* * Member variables needed to represent a news entry. */ @@ -15,16 +28,18 @@ class Page_News extends Page */ private $newsTitle = false; /** - * @var string Content as text. (TODO: html-Support?) + * @var string HTML news content */ private $newsContent = false; /** * @var int Unix epoch date of the news' creation. */ - private $newsDate = false; - private $helpContent = ''; - private $editHelp = false; - private $hasSummernote = false; + private $newsDateline = false; + /** + * @var int Unix epoch date when the news expires. + */ + private $newsExpires = false; + /** * Implementation of the abstract doPreprocess function. @@ -34,8 +49,6 @@ class Page_News extends Page */ protected function doPreprocess() { - /* load summernote module if available */ - $this->hasSummernote = Module::isAvailable('summernote'); // load user, we will need it later User::load(); @@ -45,62 +58,55 @@ class Page_News extends Page } // check which action we need to do - $action = Request::any('action', 'show'); - if ($action === 'show') { + if (!Request::isPost()) { + User::assertPermission('access-page'); - /* load latest things */ - $this->loadLatest('help'); - $this->loadLatest('news'); /* and also the news (or help) with the given id */ - if (!$this->loadNews(Request::any('newsid'))) { - Message::addError('news-empty'); + $newsId = Request::get('newsid', false, 'int'); + $pageType = Request::get('type', false, 'string'); + if ($pageType === false && $newsId === false) { + Util::redirect('?do=news&type=news'); + } + $this->pageType = $pageType === false ? 'news' : $pageType; + $this->loadNews($newsId, $pageType); + + foreach (self::TYPES as $type => $entry) { + Dashboard::addSubmenu('?do=news&type=' . $type, Dictionary::translate('type_' . $type, true)); } - if (Request::any('editHelp')) { - $this->editHelp = true; + } else { + + $action = Request::post('action', false, 'string'); + $pageType = Request::post('type', false, 'string'); + if (!array_key_exists($pageType, self::TYPES)) { + Message::addError('invalid-type', $pageType); + Util::redirect('?do=news'); } - } elseif ($action === 'save') { - // save to DB - /* find out whether it's news or help */ - $pageType = Request::post('news-type'); - if ($pageType === 'news') { - User::assertPermission("news.save"); - if (!$this->saveNews()) { - // re-set the fields we got - $this->newsTitle = Request::post('news-title', false, 'string'); - $this->newsContent = Request::post('news-content', false, 'string'); + if ($action === 'save') { + // save to DB + User::assertPermission("$pageType.save"); + if (!$this->saveNews($pageType)) { + Message::addError('save-error'); } else { Message::addSuccess('news-save-success'); - $lastId = Database::lastInsertId(); - Util::redirect("?do=News&newsid=$lastId"); - } - } elseif ($pageType === 'help') { - User::assertPermission("help.save"); - if ($this->saveHelp()) { - Message::addSuccess('help-save-success'); - $lastId = Database::lastInsertId(); - Util::redirect("?do=News&newsid=$lastId"); } - } - } elseif ($action === 'delete') { - // delete it - $pageType = Request::post('news-type'); - if ($pageType === 'news') { - User::assertPermission("news.delete"); - $this->delNews(Request::post('newsid')); - Util::redirect('?do=News&editHelp=' . Request::any('editHelp')); - } elseif ($pageType === 'help') { - User::assertPermission("help.delete"); - $this->delNews(Request::post('newsid')); - Util::redirect('?do=News&editHelp=' . Request::any('editHelp')); + } elseif ($action === 'delete') { + // delete it + User::assertPermission("$pageType.delete"); + $this->delNews(Request::post('newsid', false, 'int'), $pageType); + } else { + // unknown action, redirect user + Message::addError('invalid-action', $action); } - } else { - // unknown action, redirect user - Message::addError('invalid-action', $action); + + Util::redirect('?do=news&type=' . $pageType); } + + /* load summernote module if available */ + $this->hasSummernote = Module::isAvailable('summernote'); } /** @@ -111,152 +117,167 @@ class Page_News extends Page protected function doRender() { // fetch the list of the older news + $NOW = time(); $lines = array(); - $paginate = new Paginate("SELECT newsid, dateline, title, content FROM vmchooser_pages WHERE type='news' ORDER BY dateline DESC", 10); - $res = $paginate->exec(); + $res = Database::simpleQuery("SELECT newsid, dateline, expires, title, content FROM vmchooser_pages + WHERE type = :type ORDER BY dateline DESC LIMIT 20", ['type' => $this->pageType]); while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $row['date'] = date('d.m.Y H:i', $row['dateline']); + $row['dateline_s'] = Util::prettyTime($row['dateline']); + $row['expires_s'] = $this->formatExpires($row['expires']); + if ($row['expires'] < $NOW) { + $row['muted'] = 'text-muted'; + } if ($row['newsid'] == $this->newsId) { $row['active'] = 'active'; } - $row['content'] = strip_tags(str_replace('>', '> ', $row['content'])); + $row['content'] = substr(strip_tags(str_replace('>', '> ', $row['content'])), 0, 160); $lines[] = $row; } - // fetch the list of the older helps - $linesHelp = array(); - $paginateHelp = new Paginate("SELECT newsid, dateline, content FROM vmchooser_pages WHERE type='help' ORDER BY dateline DESC", 10); - $resHelp = $paginateHelp->exec(); - while ($row = $resHelp->fetch(PDO::FETCH_ASSOC)) { - $row['date'] = date('d.m.Y H:i', $row['dateline']); - if ($row['newsid'] == $this->newsId) { - $row['active'] = 'active'; - } - $row['content'] = strip_tags(str_replace('>', '> ', $row['content'])); - $linesHelp[] = $row; - } + $validity = ceil(($this->newsExpires - $NOW) / 3600); + if ($this->newsExpires === false || $validity > 24 * 365 * 5) { + $validity = ''; + } $data = array( - 'token' => Session::get('token'), - 'latestDate' => ($this->newsDate ? date('d.m.Y H:i', $this->newsDate) : '--'), - 'latestContent' => $this->newsContent, - 'latestTitle' => $this->newsTitle, - 'latestHelp' => $this->helpContent, - 'editHelp' => $this->editHelp, + 'withTitle' => self::TYPES[$this->pageType]['headline'], + 'newsTypeName' => Dictionary::translate('type_' . $this->pageType, true), + 'dateline_s' => Util::prettyTime($this->newsDateline), + 'expires_s' => $this->formatExpires($this->newsExpires), + 'currentContent' => $this->newsContent, + 'currentTitle' => $this->newsTitle, + 'type' => $this->pageType, + 'validity' => $validity, 'list' => $lines, - 'listHelp' => $linesHelp, 'hasSummernote' => $this->hasSummernote, ); - Permission::addGlobalTags($data['perms'], null, ['news.save', 'news.delete', 'help.save', 'help.delete']); + if (!User::hasPermission($this->pageType . '.save')) { + $data['save'] = [ + 'readonly' => 'readonly', + 'disabled' => 'disabled', + ]; + } + if (!User::hasPermission($this->pageType . '.delete')) { + $data['delete'] = [ + 'readonly' => 'readonly', + 'disabled' => 'disabled', + ]; + } + Render::addTemplate('page-news', $data); + } - $paginate->render('page-news', $data); + private function formatExpires($ts) + { + if ($ts - 86400 * 365 * 5 > time()) + return '-'; + return Util::prettyTime($ts); } /** * Loads the news with the given ID into the form. * * @param int $newsId ID of the news to be shown. + * @param string $pageType type if news id is not given. * * @return bool true if loading that news worked */ - private function loadNews($newsId) + private function loadNews($newsId, $pageType) { // check to see if we need to request a specific newsid if ($newsId !== false) { - $row = Database::queryFirst('SELECT newsid, title, content, dateline, type FROM vmchooser_pages WHERE newsid = :newsid LIMIT 1', array( + $row = Database::queryFirst('SELECT newsid, title, content, dateline, expires, type FROM vmchooser_pages + WHERE newsid = :newsid LIMIT 1', [ 'newsid' => $newsId, - )); + ]); + if ($row === false) { + Message::addError('news-empty'); + } } else { - $row = Database::queryFirst("SELECT newsid, title, content, dateline, type FROM vmchooser_pages WHERE type='news' ORDER BY dateline DESC LIMIT 1"); + $row = Database::queryFirst("SELECT newsid, title, content, dateline, expires, type FROM vmchooser_pages + WHERE type = :type AND expires > UNIX_TIMESTAMP() ORDER BY dateline DESC LIMIT 1", [ + 'type' => $pageType, + ]); } + if ($row === false) + return false; // fetch the news to be shown if ($row !== false) { - if ($row['type'] == 'news') { - $this->newsId = $row['newsid']; - $this->newsTitle = $row['title']; - $this->newsContent = $row['content']; - $this->newsDate = $row['dateline']; - $this->editHelp = false; - } else { - $this->editHelp = true; - $this->helpContent = $row['content']; - } - } - - return $row !== false; - } - - private function loadLatest($type) - { - $row = Database::queryFirst("SELECT newsid, title, content, dateline, type FROM vmchooser_pages WHERE type=:type ORDER BY dateline DESC LIMIT 1", ['type' => $type]); - if ($row !== false) { - if ($row['type'] == 'news') { - $this->newsId = $row['newsid']; - $this->newsTitle = $row['title']; - $this->newsContent = $row['content']; - $this->newsDate = $row['dateline']; - } else { - $this->helpContent = $row['content']; - } + $this->newsId = $row['newsid']; + $this->newsTitle = $row['title']; + $this->newsContent = $row['content']; + $this->newsDateline = (int)$row['dateline']; + $this->newsExpires = (int)$row['expires']; + $this->pageType = $row['type']; } + return true; } /** * Save the given $newsTitle and $newsContent as POST'ed into the database. */ - private function saveNews() + private function saveNews($pageType) { // check if news content were set by the user - $newsTitle = Request::post('news-title'); - $newsContent = Request::post('news-content'); - if ($newsContent !== '' && $newsTitle !== '') { + $newsTitle = Request::post('news-title', '', 'string'); + $newsContent = Request::post('news-content', false, 'string'); + $validity = Request::post('validity', false, 'string'); + if ($validity === false || $validity === '') { + $validity = 86400 * 3650; // 10 Years + } else { + $validity *= 3600; // Hours to seconds + } + if (!empty($newsContent)) { // we got title and content, save it to DB - Database::exec("INSERT INTO vmchooser_pages (dateline, title, content, type) VALUES (:dateline, :title, :content, 'news')", array( + // dup check first + $row = Database::queryFirst('SELECT newsid FROM vmchooser_pages + WHERE content = :content AND type = :type LIMIT 1', [ + 'content' => $newsContent, + 'type' => $pageType, + ]); + if ($row !== false) { + Database::exec('UPDATE vmchooser_pages SET dateline = :dateline, expires = :expires, title = :title + WHERE newsid = :newsid LIMIT 1', [ + 'newsid' => $row['newsid'], + 'dateline' => time(), + 'expires' => time() + $validity, + 'title' => $newsTitle, + ]); + return true; + } + // new one + Database::exec("INSERT INTO vmchooser_pages (dateline, expires, title, content, type) + VALUES (:dateline, :expires, :title, :content, :type)", array( 'dateline' => time(), + 'expires' => time() + $validity, 'title' => $newsTitle, 'content' => $newsContent, + 'type' => $pageType, )); return true; - } else { - Message::addError('main.empty-field'); - - return false; } - } - - private function saveHelp() - { - $content = Request::post('help-content'); - if ($content !== '') { - Database::exec("INSERT INTO vmchooser_pages (dateline, content, type) VALUES (:dateline, :content, 'help')", array( - 'dateline' => time(), - 'content' => $content, - )); - - return true; - } else { - Message::addError('main.empty-field'); - return false; - } + Message::addError('main.empty-field'); + return false; } /** * Delete the news entry with ID $newsId. * * @param int $newsId ID of the entry to be deleted. + * @param string $pageType type of news to be deleted. Must match the ID, otherwise do nothing. */ - private function delNews($newsId) + private function delNews($newsId, $pageType) { // sanity check: is newsId even numeric? if (!is_numeric($newsId)) { Message::addError('main.value-invalid', 'newsid', $newsId); } else { // check passed - do delete - Database::exec('DELETE FROM vmchooser_pages WHERE newsid = :newsid LIMIT 1', array( + Database::exec('DELETE FROM vmchooser_pages WHERE newsid = :newsid AND type = :type LIMIT 1', array( 'newsid' => $newsId, + 'type' => $pageType, )); Message::addSuccess('news-del-success'); } diff --git a/modules-available/news/permissions/permissions.json b/modules-available/news/permissions/permissions.json index 953599df..4ff1a01b 100644 --- a/modules-available/news/permissions/permissions.json +++ b/modules-available/news/permissions/permissions.json @@ -13,5 +13,11 @@ }, "news.save": { "location-aware": false + }, + "login-news.delete": { + "location-aware": false + }, + "login-news.save": { + "location-aware": false } } \ No newline at end of file diff --git a/modules-available/news/templates/page-news.html b/modules-available/news/templates/page-news.html index 43afaf1a..0543a414 100644 --- a/modules-available/news/templates/page-news.html +++ b/modules-available/news/templates/page-news.html @@ -1,129 +1,89 @@ -

{{lang_vmChooser_title}}

+

{{lang_mainHeading}}

- +

{{lang_introText}}

-
-
-
-

{{lang_newsIntro}}

-
- - -
-
- - -
-
-
-

{{lang_latestUpdate}}: {{latestDate}}

-
-
- - -
-
+

{{newsTypeName}}

-
-
-
-
- {{lang_newsOld}} -
-
-
-
- - - - - - - - - - - - {{#list}} - - - - - - - - {{/list}} - -
{{lang_date}}{{lang_title}}{{lang_content}}{{lang_show}}{{lang_delete}}
{{date}}
{{title}}
{{content}}
- - - - -
- -
-
-
-
+
+ + + + {{#withTitle}} +
+ + +
+ {{/withTitle}} +
+ ({{lang_leaveEmptyInfinite}}) + +
+
+ + +
+
+ {{lang_lastUpdate}}: {{dateline_s}} +
+ {{lang_expires}}: {{expires_s}}
-
- -
-
- - -
-
- +
+ +
+ + +

+
+
+ {{lang_previousEntries}} +
+
+
+
-
- -
-
-
- {{lang_oldHelp}} -
-
-
-
- - - - - - - - - - - {{#listHelp}} - - - - - - - {{/listHelp}} - -
{{lang_date}}{{lang_content}}{{lang_show}}{{lang_delete}}
{{date}}
{{content}}
- - - - -
- -
-
-
+ + + + + + + + + + + + + + + {{#list}} + + + + + + + + + {{/list}} + +
{{lang_created}}{{lang_expires}}{{lang_title}}{{lang_content}}{{lang_show}}{{lang_delete}}
{{dateline_s}}{{expires_s}}
{{title}}
{{content}}
+ + + + + +
+
+ \ No newline at end of file -- cgit v1.2.3-55-g7522