From 69e0d59d9f8b3674c5479e68f8903f120c4a453f Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Wed, 10 May 2017 17:18:30 +0200 Subject: [PATCH] Render sources in navigation client-side Use EJS to render them --- controllers/Index.php | 29 ++++++-------- controllers/Items.php | 6 +-- controllers/Sources.php | 53 +------------------------- helpers/View.php | 32 +++++++++++++++- index.php | 7 +++- public/js/selfoss-base.js | 4 +- public/js/selfoss-db.js | 4 +- public/js/selfoss-events-navigation.js | 4 +- public/package.json | 2 + templates/source-nav.ejs | 8 ++++ templates/source-nav.phtml | 8 ---- 11 files changed, 69 insertions(+), 88 deletions(-) create mode 100644 templates/source-nav.ejs delete mode 100644 templates/source-nav.phtml diff --git a/controllers/Index.php b/controllers/Index.php index df980565e1..12b4e70a72 100644 --- a/controllers/Index.php +++ b/controllers/Index.php @@ -65,29 +65,24 @@ public function home(Base $f3) { $tagsController = new \controllers\Tags(); $this->view->tags = $tagsController->renderTags($tags); + $result = [ + 'lastUpdate' => \helpers\ViewHelper::date_iso8601($itemsDao->lastUpdate()), + 'hasMore' => $items['hasMore'], + 'entries' => $this->view->content, + 'all' => $this->view->statsAll, + 'unread' => $this->view->statsUnread, + 'starred' => $this->view->statsStarred, + 'tags' => $this->view->tags, + ]; + if (isset($options['sourcesNav']) && $options['sourcesNav'] == 'true') { // prepare sources display list $sourcesDao = new \daos\Sources(); - $sources = $sourcesDao->getWithUnread(); - $sourcesController = new \controllers\Sources(); - $this->view->sources = $sourcesController->renderSources($sources); - } else { - $this->view->sources = ''; + $result['sources'] = $sourcesDao->getWithUnread(); } // ajax call = only send entries and statistics not full template - if ($f3->ajax()) { - $this->view->jsonSuccess([ - 'lastUpdate' => \helpers\ViewHelper::date_iso8601($itemsDao->lastUpdate()), - 'hasMore' => $items['hasMore'], - 'entries' => $this->view->content, - 'all' => $this->view->statsAll, - 'unread' => $this->view->statsUnread, - 'starred' => $this->view->statsStarred, - 'tags' => $this->view->tags, - 'sources' => $this->view->sources - ]); - } + $this->view->jsonSuccess($result); } /** diff --git a/controllers/Items.php b/controllers/Items.php index d77f58ad23..26211c7ced 100644 --- a/controllers/Items.php +++ b/controllers/Items.php @@ -175,8 +175,7 @@ public function stats() { } if (array_key_exists('sources', $_GET) && $_GET['sources'] == 'true') { $sourcesDao = new \daos\Sources(); - $sourcesController = new \controllers\Sources(); - $stats['sourceshtml'] = $sourcesController->renderSources($sourcesDao->getWithUnread()); + $stats['sources'] = $sourcesDao->getWithUnread(); } $this->view->jsonSuccess($stats); @@ -263,8 +262,7 @@ public function sync() { } if (array_key_exists('sources', $params) && $_GET['sources'] == 'true') { $sourcesDao = new \daos\Sources(); - $sourcesController = new \controllers\Sources(); - $sync['sourceshtml'] = $sourcesController->renderSources($sourcesDao->getWithUnread()); + $sync['sources'] = $sourcesDao->getWithUnread(); } $wantItemsStatuses = array_key_exists('itemsStatuses', $params) && $params['itemsStatuses'] == 'true'; diff --git a/controllers/Sources.php b/controllers/Sources.php index e01e2dba84..6c369cf000 100644 --- a/controllers/Sources.php +++ b/controllers/Sources.php @@ -82,40 +82,6 @@ public function params() { } } - /** - * return all Sources suitable for navigation panel - * html - * - * @param array $sources - * - * @return string htmltext - */ - public function renderSources(array $sources) { - $html = ''; - foreach ($sources as $source) { - $this->view->source = $source['title']; - $this->view->sourceid = $source['id']; - $this->view->unread = $source['unread']; - $html .= $this->view->render('templates/source-nav.phtml'); - } - - return $html; - } - - /** - * load all available sources and return all Sources suitable - * for navigation panel - * html - * - * @return string htmltext - */ - public function sourcesListAsString() { - $sourcesDao = new \daos\Sources(); - $sources = $sourcesDao->getWithUnread(); - - return $this->renderSources($sources); - } - /** * render spouts params * json @@ -222,28 +188,13 @@ public function write(Base $f3, array $params) { $return['tags'] = $tagController->tagsListAsString(); // get new sources list - $sourcesController = new \controllers\Sources(); - $return['sources'] = $sourcesController->sourcesListAsString(); + $sourcesDao = new \daos\Sources(); + $return['sources'] = $sourcesDao->getWithUnread(); } $this->view->jsonSuccess($return); } - /** - * return source stats in HTML for nav update - * json - * - * @return void - */ - public function sourcesStats() { - $this->needsLoggedInOrPublicMode(); - - $this->view->jsonSuccess([ - 'success' => true, - 'sources' => $this->sourcesListAsString() - ]); - } - /** * delete source * json diff --git a/helpers/View.php b/helpers/View.php index f21512bc71..755c36e102 100644 --- a/helpers/View.php +++ b/helpers/View.php @@ -184,7 +184,12 @@ public static function getGlobalCssFileName() { * @return void */ private function genMinified($type) { - self::$staticmtime[$type] = self::maxmtime(\F3::get($type)); + $watchedFiles = \F3::get($type); + if ($type === self::STATIC_RESOURCE_JS) { + $watchedFiles = array_merge($watchedFiles, array_values(\F3::get('ejs'))); + } + + self::$staticmtime[$type] = self::maxmtime($watchedFiles); $target = \F3::get('BASEDIR') . '/public/' . self::$staticPrefix . '.' . $type; @@ -199,6 +204,12 @@ private function genMinified($type) { } $minified = $minified . "\n" . $minifiedFile; } + + if ($type === self::STATIC_RESOURCE_JS) { + $combined = self::combineTemplates(\F3::get('ejs')); + $minified = $minified . "\n" . $combined; + } + file_put_contents($target, $minified); } } @@ -309,4 +320,23 @@ public function genOfflineSW() { file_put_contents($target, $offlineWorker); } } + + /** + * creates a file combining templates for easy access from client + * + * @param array $files + * + * @return string combined templates + */ + private static function combineTemplates(array $files) { + $result = 'selfoss.templates = {'; + foreach ($files as $name => $file) { + $template = file_get_contents(\F3::get('BASEDIR') . '/' . $file); + $result .= json_encode($name) . ': ejs.compile(' . json_encode($template) . ', {"delimiter": "?"}),'; + } + + $result .= '};'; + + return $result; + } } diff --git a/index.php b/index.php index 6f4376d90c..43bffacae3 100644 --- a/index.php +++ b/index.php @@ -21,6 +21,12 @@ } $f3->set('js', $js); +// define ejs templates +$ejs = [ + 'navSources' => 'templates/source-nav.ejs', +]; +$f3->set('ejs', $ejs); + // define css files $css = $clientPackage->extra->requiredFiles->css; if (file_exists('user.css')) { @@ -63,7 +69,6 @@ $f3->route('GET /sources', 'controllers\Sources->show'); // html $f3->route('GET /source', 'controllers\Sources->add'); // html $f3->route('GET /sources/list', 'controllers\Sources->listSources'); // json -$f3->route('GET /sources/sourcesStats', 'controllers\Sources->sourcesStats'); // json $f3->route('POST /source/@id', 'controllers\Sources->write'); // json $f3->route('POST /source', 'controllers\Sources->write'); // json $f3->route('DELETE /source/@id', 'controllers\Sources->remove'); // json diff --git a/public/js/selfoss-base.js b/public/js/selfoss-base.js index 48a402503d..5633e18416 100644 --- a/public/js/selfoss-base.js +++ b/public/js/selfoss-base.js @@ -391,8 +391,8 @@ var selfoss = { * @param sources the new sourceslist as html */ refreshSources: function(sources) { - $('#nav-sources li').remove(); - $('#nav-sources').append(sources); + var renderedSources = selfoss.templates.navSources({sources: sources}); + $('#nav-sources').html(renderedSources); if (selfoss.filter.source) { if (!selfoss.db.isValidSource(selfoss.filter.source)) { selfoss.ui.showError($('#lang').data('error_unknown_source') + ' ' diff --git a/public/js/selfoss-db.js b/public/js/selfoss-db.js index b352518cdc..4f83c0ff56 100644 --- a/public/js/selfoss-db.js +++ b/public/js/selfoss-db.js @@ -185,8 +185,8 @@ selfoss.dbOnline = { selfoss.refreshTags(data.tagshtml); } - if ('sourceshtml' in data) { - selfoss.refreshSources(data.sourceshtml); + if ('sources' in data) { + selfoss.refreshSources(data.sources); } if ('stats' in data && data.stats.unread > 0 && diff --git a/public/js/selfoss-events-navigation.js b/public/js/selfoss-events-navigation.js index fdf76a312e..1e3ed7d794 100644 --- a/public/js/selfoss-events-navigation.js +++ b/public/js/selfoss-events-navigation.js @@ -129,10 +129,10 @@ selfoss.events.navigation = function() { selfoss.filter.sourcesNav = $('#nav-sources-title').hasClass('nav-sources-collapsed'); if (selfoss.filter.sourcesNav && !selfoss.sourcesNavLoaded) { $.ajax({ - url: $('base').attr('href') + 'sources/sourcesStats', + url: $('base').attr('href') + 'sources/stats', type: 'GET', success: function(data) { - selfoss.refreshSources(data.sources); + selfoss.refreshSources(data); }, error: function(jqXHR, textStatus, errorThrown) { selfoss.ui.showError($('#lang').data('error_loading_stats') + ' ' + diff --git a/public/package.json b/public/package.json index 78c2c91e77..fc57cf8fa8 100644 --- a/public/package.json +++ b/public/package.json @@ -1,5 +1,6 @@ { "dependencies": { + "ejs": "^2.5.6", "@fancyapps/fancybox": "^3.1.20", "dexie": "^2.0.1", "jquery": "^2.2.4", @@ -18,6 +19,7 @@ "public/css/style.css" ], "js": [ + "public/node_modules/ejs/ejs.js", "public/node_modules/jquery/dist/jquery.js", "public/node_modules/jquery-mousewheel/jquery.mousewheel.js", "public/node_modules/malihu-custom-scrollbar-plugin/jquery.mCustomScrollbar.js", diff --git a/templates/source-nav.ejs b/templates/source-nav.ejs new file mode 100644 index 0000000000..65f10b6b02 --- /dev/null +++ b/templates/source-nav.ejs @@ -0,0 +1,8 @@ + +
  • + + 0) { ?> + + +
  • + diff --git a/templates/source-nav.phtml b/templates/source-nav.phtml deleted file mode 100644 index 4bda3e60ac..0000000000 --- a/templates/source-nav.phtml +++ /dev/null @@ -1,8 +0,0 @@ -
  • - source; ?> - unread > 0) { - echo $this->unread; -} ?> -