Merge pull request #481 from ZogStriP/selecting-default-landing-tab
FIX: allows the selection of the default landing tab
This commit is contained in:
commit
08267f5171
8 changed files with 81 additions and 88 deletions
app
assets/javascripts/discourse
controllers
models
config
lib
spec/controllers
|
@ -14,7 +14,7 @@ Discourse.ListController = Discourse.Controller.extend({
|
||||||
canCreateTopic: false,
|
canCreateTopic: false,
|
||||||
needs: ['composer', 'modal', 'listTopics'],
|
needs: ['composer', 'modal', 'listTopics'],
|
||||||
|
|
||||||
availableNavItems: (function() {
|
availableNavItems: function() {
|
||||||
var hasCategories, loggedOn, summary;
|
var hasCategories, loggedOn, summary;
|
||||||
summary = this.get('filterSummary');
|
summary = this.get('filterSummary');
|
||||||
loggedOn = !!Discourse.get('currentUser');
|
loggedOn = !!Discourse.get('currentUser');
|
||||||
|
@ -28,7 +28,7 @@ Discourse.ListController = Discourse.Controller.extend({
|
||||||
}).filter(function(i) {
|
}).filter(function(i) {
|
||||||
return i !== null;
|
return i !== null;
|
||||||
});
|
});
|
||||||
}).property('filterSummary'),
|
}.property('filterSummary'),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Load a list based on a filter
|
Load a list based on a filter
|
||||||
|
@ -63,26 +63,23 @@ Discourse.ListController = Discourse.Controller.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
// Put in the appropriate page title based on our view
|
// Put in the appropriate page title based on our view
|
||||||
updateTitle: (function() {
|
updateTitle: function() {
|
||||||
if (this.get('filterMode') === 'categories') {
|
if (this.get('filterMode') === 'categories') {
|
||||||
return Discourse.set('title', Em.String.i18n('categories_list'));
|
return Discourse.set('title', Em.String.i18n('categories_list'));
|
||||||
} else {
|
} else {
|
||||||
if (this.present('category')) {
|
if (this.present('category')) {
|
||||||
return Discourse.set('title', "" + (this.get('category.name').capitalize()) + " " + (Em.String.i18n('topic.list')));
|
return Discourse.set('title', this.get('category.name').capitalize() + " " + Em.String.i18n('topic.list'));
|
||||||
} else {
|
} else {
|
||||||
return Discourse.set('title', Em.String.i18n('topic.list'));
|
return Discourse.set('title', Em.String.i18n('topic.list'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).observes('filterMode', 'category'),
|
}.observes('filterMode', 'category'),
|
||||||
|
|
||||||
// Create topic button
|
// Create topic button
|
||||||
createTopic: function() {
|
createTopic: function() {
|
||||||
var topicList;
|
var topicList = this.get('controllers.listTopics.content');
|
||||||
topicList = this.get('controllers.listTopics.content');
|
if (!topicList) return;
|
||||||
if (!topicList) {
|
this.get('controllers.composer').open({
|
||||||
return;
|
|
||||||
}
|
|
||||||
return this.get('controllers.composer').open({
|
|
||||||
categoryName: this.get('category.name'),
|
categoryName: this.get('category.name'),
|
||||||
action: Discourse.Composer.CREATE_TOPIC,
|
action: Discourse.Composer.CREATE_TOPIC,
|
||||||
draftKey: topicList.get('draft_key'),
|
draftKey: topicList.get('draft_key'),
|
||||||
|
@ -100,5 +97,3 @@ Discourse.ListController = Discourse.Controller.extend({
|
||||||
Discourse.ListController.reopenClass({
|
Discourse.ListController.reopenClass({
|
||||||
filters: ['latest', 'hot', 'favorited', 'read', 'unread', 'new', 'posted']
|
filters: ['latest', 'hot', 'favorited', 'read', 'unread', 'new', 'posted']
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,47 +6,35 @@
|
||||||
@namespace Discourse
|
@namespace Discourse
|
||||||
@module Discourse
|
@module Discourse
|
||||||
**/
|
**/
|
||||||
var validNavNames = ['read', 'latest', 'hot', 'categories', 'favorited', 'category', 'unread', 'new', 'posted'];
|
var validNavNames = ['latest', 'hot', 'categories', 'category', 'favorited', 'unread', 'new', 'read', 'posted'];
|
||||||
var validAnon = ['latest', 'hot', 'category', 'categories'];
|
var validAnon = ['latest', 'hot', 'categories', 'category'];
|
||||||
|
|
||||||
Discourse.NavItem = Discourse.Model.extend({
|
Discourse.NavItem = Discourse.Model.extend({
|
||||||
categoryName: (function() {
|
categoryName: function() {
|
||||||
var split;
|
var split = this.get('name').split('/');
|
||||||
split = this.get('name').split('/');
|
return split[0] === 'category' ? split[1] : null;
|
||||||
if (split[0] === 'category') {
|
}.property('name'),
|
||||||
return split[1];
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}).property(),
|
|
||||||
href: (function() {
|
|
||||||
/* href from this item
|
|
||||||
*/
|
|
||||||
|
|
||||||
var name;
|
// href from this item
|
||||||
name = this.get('name');
|
href: function() {
|
||||||
if (name === 'category') {
|
var name = this.get('name'),
|
||||||
return Discourse.getURL("/") + name + "/" + (this.get('categoryName'));
|
href = Discourse.getURL("/") + name;
|
||||||
} else {
|
if (name === 'category') href += "/" + this.get('categoryName');
|
||||||
return Discourse.getURL("/") + name;
|
return href;
|
||||||
}
|
}.property('name')
|
||||||
}).property()
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Discourse.NavItem.reopenClass({
|
Discourse.NavItem.reopenClass({
|
||||||
|
|
||||||
// create a nav item from the text, will return null if there is not valid nav item for this particular text
|
// create a nav item from the text, will return null if there is not valid nav item for this particular text
|
||||||
fromText: function(text, opts) {
|
fromText: function(text, opts) {
|
||||||
var countSummary, hasCategories, loggedOn, name, split, testName;
|
var countSummary = opts.countSummary,
|
||||||
countSummary = opts.countSummary;
|
split = text.split(","),
|
||||||
loggedOn = opts.loggedOn;
|
name = split[0],
|
||||||
hasCategories = opts.hasCategories;
|
testName = name.split("/")[0];
|
||||||
split = text.split(",");
|
|
||||||
name = split[0];
|
|
||||||
testName = name.split("/")[0];
|
|
||||||
|
|
||||||
if (!loggedOn && !validAnon.contains(testName)) return null;
|
if (!opts.loggedOn && !validAnon.contains(testName)) return null;
|
||||||
if (!hasCategories && testName === "categories") return null;
|
if (!opts.hasCategories && testName === "categories") return null;
|
||||||
if (!validNavNames.contains(testName)) return null;
|
if (!validNavNames.contains(testName)) return null;
|
||||||
|
|
||||||
opts = {
|
opts = {
|
||||||
|
@ -54,14 +42,10 @@ Discourse.NavItem.reopenClass({
|
||||||
hasIcon: name === "unread" || name === "favorited",
|
hasIcon: name === "unread" || name === "favorited",
|
||||||
filters: split.splice(1)
|
filters: split.splice(1)
|
||||||
};
|
};
|
||||||
if (countSummary) {
|
|
||||||
if (countSummary && countSummary[name]) {
|
if (countSummary && countSummary[name]) opts.count = countSummary[name];
|
||||||
opts.count = countSummary[name];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Discourse.NavItem.create(opts);
|
return Discourse.NavItem.create(opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -19,22 +19,20 @@ Discourse.Route.buildRoutes(function() {
|
||||||
router.route(p, { path: "/" + p });
|
router.route(p, { path: "/" + p });
|
||||||
});
|
});
|
||||||
|
|
||||||
this.route('faq', { path: '/faq' });
|
|
||||||
this.route('tos', { path: '/tos' });
|
|
||||||
this.route('privacy', { path: '/privacy' });
|
|
||||||
|
|
||||||
// List routes
|
// List routes
|
||||||
this.resource('list', { path: '/' }, function() {
|
this.resource('list', { path: '/' }, function() {
|
||||||
router = this;
|
router = this;
|
||||||
|
|
||||||
// Generate routes for all our filters
|
// Generate routes for all our filters
|
||||||
Discourse.ListController.filters.forEach(function(r) {
|
Discourse.ListController.filters.forEach(function(filter) {
|
||||||
router.route(r, { path: "/" + r });
|
router.route(filter, { path: "/" + filter });
|
||||||
router.route(r, { path: "/" + r + "/more" });
|
router.route(filter, { path: "/" + filter + "/more" });
|
||||||
});
|
});
|
||||||
|
|
||||||
this.route('latest', { path: '/' });
|
// the homepage is the first item of the 'top_menu' site setting
|
||||||
this.route('hot', { path: '/hot' });
|
var homepage = PreloadStore.get('siteSettings').top_menu.split("|")[0];
|
||||||
|
this.route(homepage, { path: '/' });
|
||||||
|
|
||||||
this.route('categories', { path: '/categories' });
|
this.route('categories', { path: '/categories' });
|
||||||
this.route('category', { path: '/category/:slug/more' });
|
this.route('category', { path: '/category/:slug/more' });
|
||||||
this.route('category', { path: '/category/:slug' });
|
this.route('category', { path: '/category/:slug' });
|
||||||
|
@ -51,5 +49,3 @@ Discourse.Route.buildRoutes(function() {
|
||||||
this.route('invited', { path: 'invited' });
|
this.route('invited', { path: 'invited' });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
class ListController < ApplicationController
|
class ListController < ApplicationController
|
||||||
|
|
||||||
before_filter :ensure_logged_in, except: [:index, :hot, :category, :category_feed]
|
before_filter :ensure_logged_in, except: [:latest, :hot, :category, :category_feed]
|
||||||
skip_before_filter :check_xhr
|
skip_before_filter :check_xhr
|
||||||
|
|
||||||
# Create our filters
|
# Create our filters
|
||||||
[:latest, :hot, :favorited, :read, :posted, :unread, :new].each do |filter|
|
[:latest, :hot, :favorited, :read, :posted, :unread, :new].each do |filter|
|
||||||
define_method(filter) do
|
define_method(filter) do
|
||||||
|
|
||||||
list_opts = {page: params[:page]}
|
list_opts = {page: params[:page]}
|
||||||
|
|
||||||
# html format means we need to farm exclude from the site options
|
# html format means we need to farm exclude from the site options
|
||||||
|
@ -14,7 +13,7 @@ class ListController < ApplicationController
|
||||||
#TODO objectify this stuff
|
#TODO objectify this stuff
|
||||||
SiteSetting.top_menu.split('|').each do |f|
|
SiteSetting.top_menu.split('|').each do |f|
|
||||||
s = f.split(",")
|
s = f.split(",")
|
||||||
if s[0] == action_name || (action_name == "index" && s[0] == "latest")
|
if s[0] == action_name || (action_name == "index" && s[0] == SiteSetting.homepage)
|
||||||
list_opts[:exclude_category] = s[1][1..-1] if s.length == 2
|
list_opts[:exclude_category] = s[1][1..-1] if s.length == 2
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -27,7 +26,6 @@ class ListController < ApplicationController
|
||||||
respond(list)
|
respond(list)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
alias_method :index, :latest
|
|
||||||
|
|
||||||
def category
|
def category
|
||||||
|
|
||||||
|
|
|
@ -190,4 +190,13 @@ class SiteSetting < ActiveRecord::Base
|
||||||
def self.post_length
|
def self.post_length
|
||||||
min_post_length..max_post_length
|
min_post_length..max_post_length
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.homepage
|
||||||
|
top_menu.split('|')[0]
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.anonymous_homepage
|
||||||
|
top_menu.split('|').select{ |f| ['latest', 'hot', 'categories', 'category'].include? f }[0]
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
require 'sidekiq/web'
|
require 'sidekiq/web'
|
||||||
|
|
||||||
require_dependency 'admin_constraint'
|
require_dependency 'admin_constraint'
|
||||||
|
require_dependency 'homepage_constraint'
|
||||||
|
|
||||||
# This used to be User#username_format, but that causes a preload of the User object
|
# This used to be User#username_format, but that causes a preload of the User object
|
||||||
# and makes Guard not work properly.
|
# and makes Guard not work properly.
|
||||||
|
@ -154,20 +155,10 @@ Discourse::Application.routes.draw do
|
||||||
get 'popular' => 'list#popular_redirect'
|
get 'popular' => 'list#popular_redirect'
|
||||||
get 'popular/more' => 'list#popular_redirect'
|
get 'popular/more' => 'list#popular_redirect'
|
||||||
|
|
||||||
get 'latest' => 'list#index'
|
[:latest, :hot, :favorited, :read, :posted, :unread, :new].each do |filter|
|
||||||
get 'latest/more' => 'list#index'
|
get "#{filter}" => "list##{filter}"
|
||||||
get 'hot' => 'list#hot'
|
get "#{filter}/more" => "list##{filter}"
|
||||||
get 'hot/more' => 'list#hot'
|
end
|
||||||
get 'favorited' => 'list#favorited'
|
|
||||||
get 'favorited/more' => 'list#favorited'
|
|
||||||
get 'read' => 'list#read'
|
|
||||||
get 'read/more' => 'list#read'
|
|
||||||
get 'unread' => 'list#unread'
|
|
||||||
get 'unread/more' => 'list#unread'
|
|
||||||
get 'new' => 'list#new'
|
|
||||||
get 'new/more' => 'list#new'
|
|
||||||
get 'posted' => 'list#posted'
|
|
||||||
get 'posted/more' => 'list#posted'
|
|
||||||
|
|
||||||
get 'search' => 'search#query'
|
get 'search' => 'search#query'
|
||||||
|
|
||||||
|
@ -222,11 +213,12 @@ Discourse::Application.routes.draw do
|
||||||
post 'draft' => 'draft#update'
|
post 'draft' => 'draft#update'
|
||||||
delete 'draft' => 'draft#destroy'
|
delete 'draft' => 'draft#destroy'
|
||||||
|
|
||||||
|
|
||||||
get 'robots.txt' => 'robots_txt#index'
|
get 'robots.txt' => 'robots_txt#index'
|
||||||
|
|
||||||
# You can have the root of your site routed with "root"
|
[:latest, :hot, :unread, :new, :favorited, :read, :posted].each do |filter|
|
||||||
# just remember to delete public/index.html.
|
root to: "list##{filter}", constraints: HomePageConstraint.new("#{filter}")
|
||||||
root to: 'list#index'
|
end
|
||||||
|
# special case for categories
|
||||||
|
root to: "categories#index", constraints: HomePageConstraint.new("categories")
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
10
lib/homepage_constraint.rb
Normal file
10
lib/homepage_constraint.rb
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
class HomePageConstraint
|
||||||
|
def initialize(filter)
|
||||||
|
@filter = filter
|
||||||
|
end
|
||||||
|
|
||||||
|
def matches?(request)
|
||||||
|
homepage = request.session[:current_user_id].present? ? SiteSetting.homepage : SiteSetting.anonymous_homepage
|
||||||
|
homepage == @filter
|
||||||
|
end
|
||||||
|
end
|
|
@ -8,12 +8,21 @@ describe ListController do
|
||||||
@post = Fabricate(:post, user: @user)
|
@post = Fabricate(:post, user: @user)
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'index' do
|
describe 'indexes' do
|
||||||
before do
|
|
||||||
xhr :get, :index
|
[:latest, :hot].each do |filter|
|
||||||
|
context '#{filter}' do
|
||||||
|
before { xhr :get, filter }
|
||||||
|
it { should respond_with(:success) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
[:favorited, :read, :posted, :unread, :new].each do |filter|
|
||||||
|
context '#{filter}' do
|
||||||
|
it { expect { xhr :get, filter }.to raise_error(Discourse::NotLoggedIn) }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it { should respond_with(:success) }
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'category' do
|
context 'category' do
|
||||||
|
|
Reference in a new issue