Skip to content

Commit

Permalink
FEATURE: add a global setting to support custom docs url path (#107)
Browse files Browse the repository at this point in the history
* FEATURE: add a global setting to support custom docs url path

This commit adds a GlobalSetting `docs_path` to support custom docs url
path for sites that do not want docs page to live at `/docs` and have a
customized path.

* Fixed the route declaration

* Test and linting

* Update server.en.yml

* Fixed doc test

* Fixed linting.

* Testing qunit test fix

* Fixed tests

* Prettified tests

* Changed the implementation from SiteSetting to GlobalSetting instead.

* Fixed tests

* Cleanup

* Using Site instead of .js.erb to pass GlobalSetting.docs_url to the front end.

Also fixed front end tests

* Remove references to obsolete site setting

* remove unused fixture file

* Rename `docs_url` to `docs_path` and use camelCase in JavaScript

* Add serializer tests

Co-authored-by: Arpit Jalan <er.ajalan@gmail.com>
  • Loading branch information
frank3manuel and arpitjalan committed Nov 17, 2022
1 parent f1dd03f commit 6b3f257
Show file tree
Hide file tree
Showing 16 changed files with 104 additions and 41 deletions.
2 changes: 2 additions & 0 deletions assets/javascripts/discourse/components/docs-topic-list.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import Component from "@ember/component";
import { action } from "@ember/object";
import discourseComputed from "discourse-common/utils/decorators";
import { getDocs } from "../../lib/get-docs";

export default Component.extend({
classNames: "docs-topic-list",
urlPath: getDocs(),

@discourseComputed("order")
sortTitle(order) {
Expand Down
6 changes: 5 additions & 1 deletion assets/javascripts/discourse/docs-route-map.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { getDocs } from "../lib/get-docs";

export default function () {
this.route("docs", { path: "/docs" }, function () {
const docsPath = getDocs();

this.route("docs", { path: "/" + docsPath }, function () {
this.route("index", { path: "/" });
});
}
8 changes: 6 additions & 2 deletions assets/javascripts/discourse/initializers/setup-docs.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import { withPluginApi } from "discourse/lib/plugin-api";
import I18n from "I18n";
import { getDocs } from "../../lib/get-docs";

function initialize(api, container) {
const siteSettings = container.lookup("site-settings:main");
const docsPath = getDocs();

api.addKeyboardShortcut("g e", "", { path: "/docs" });
api.addKeyboardShortcut("g e", "", {
path: "/" + docsPath,
});

if (siteSettings.docs_add_to_top_menu) {
api.addNavigationBarItem({
name: "docs",
displayName: I18n.t("docs.title"),
href: "/docs",
href: "/" + docsPath,
});
}
}
Expand Down
4 changes: 3 additions & 1 deletion assets/javascripts/discourse/models/docs.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import EmberObject from "@ember/object";
import { ajax } from "discourse/lib/ajax";
import Topic from "discourse/models/topic";
import { getDocs } from "../../lib/get-docs";

const Docs = EmberObject.extend({});
const docsPath = getDocs();

Docs.reopenClass({
list(params) {
Expand Down Expand Up @@ -34,7 +36,7 @@ Docs.reopenClass({
filters.push("track_visit=true");
}

return ajax(`/docs.json?${filters.join("&")}`).then((data) => {
return ajax(`/${docsPath}.json?${filters.join("&")}`).then((data) => {
data.topics.topic_list.topics = data.topics.topic_list.topics.map(
(topic) => Topic.create(topic)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

<tbody class="topic-list-body">
{{#each topics as |topic|}}
{{raw "docs-topic-list-item" topic=topic}}
{{raw "docs-topic-list-item" topic=topic urlPath=urlPath}}
{{/each}}
</tbody>
</table>
Expand Down
2 changes: 1 addition & 1 deletion assets/javascripts/discourse/templates/docs-topic-link.hbr
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<a href="/docs?topic={{topic.id}}" class="docs-topic-link">{{{topic.fancyTitle}}}</a>
<a href="/{{urlPath}}?topic={{topic.id}}" class="docs-topic-link">{{{topic.fancyTitle}}}</a>
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<td class="main-link topic-list-data">
<span class="link-top-line">
{{~raw "topic-status" topic=topic}}
{{~raw "docs-topic-link" topic=topic}}
{{~raw "docs-topic-link" topic=topic urlPath=urlPath}}
</span>
<span class="link-bottom-line">
{{category-link topic.category}}
Expand Down
5 changes: 5 additions & 0 deletions assets/javascripts/lib/get-docs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import Site from "discourse/models/site";

export function getDocs() {
return Site.currentProp("docs_path") || "docs";
}
4 changes: 2 additions & 2 deletions lib/docs/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ class Engine < ::Rails::Engine

config.after_initialize do
Discourse::Application.routes.append do
mount ::Docs::Engine, at: '/docs'
get '/knowledge-explorer', to: redirect("/docs")
mount ::Docs::Engine, at: "/#{GlobalSetting.docs_path}"
get '/knowledge-explorer', to: redirect("/#{GlobalSetting.docs_path}")
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/docs/query.rb
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ def load_more_url
filters.push('page=1')
end

"/docs.json?#{filters.join('&')}"
"/#{GlobalSetting.docs_path}.json?#{filters.join('&')}"
end
end
end
8 changes: 7 additions & 1 deletion plugin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
load File.expand_path('lib/docs/engine.rb', __dir__)
load File.expand_path('lib/docs/query.rb', __dir__)

GlobalSetting.add_default :docs_path, "docs"

after_initialize do
require_dependency 'search'

Expand Down Expand Up @@ -55,6 +57,10 @@
end

any_user_agent[:disallow] ||= []
any_user_agent[:disallow] << "/docs/"
any_user_agent[:disallow] << "/#{GlobalSetting.docs_path}/"
end

add_to_serializer(:site, :docs_path) do
GlobalSetting.docs_path
end
end
43 changes: 22 additions & 21 deletions spec/requests/docs_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@
SiteSetting.docs_enabled = true
SiteSetting.docs_categories = category.id.to_s
SiteSetting.docs_tags = 'test'
GlobalSetting.stubs(:docs_path).returns('docs')
end

describe 'docs data' do
context 'when any user' do
it 'should return the right response' do
get '/docs.json'
get "/#{GlobalSetting.docs_path}.json"

expect(response.status).to eq(200)

Expand All @@ -31,7 +32,7 @@
end

it 'should return a topic count' do
get '/docs.json'
get "/#{GlobalSetting.docs_path}.json"

json = response.parsed_body
topic_count = json['topic_count']
Expand All @@ -50,7 +51,7 @@
end

it 'should not show topics in private categories without permissions' do
get '/docs.json'
get "/#{GlobalSetting.docs_path}.json"

json = JSON.parse(response.body)
topics = json['topics']['topic_list']['topics']
Expand All @@ -62,7 +63,7 @@
admin = Fabricate(:admin)
sign_in(admin)

get '/docs.json'
get "/#{GlobalSetting.docs_path}.json"

json = JSON.parse(response.body)
topics = json['topics']['topic_list']['topics']
Expand All @@ -76,7 +77,7 @@
fab!(:tag3) { Fabricate(:tag, topics: [topic], name: 'test3') }

it 'should return a list filtered by tag' do
get '/docs.json?tags=test'
get "/#{GlobalSetting.docs_path}.json?tags=test"

expect(response.status).to eq(200)

Expand All @@ -87,7 +88,7 @@
end

it 'should properly filter with more than two tags' do
get '/docs.json?tags=test%7ctest2%7ctest3'
get "/#{GlobalSetting.docs_path}.json?tags=test%7ctest2%7ctest3"

expect(response.status).to eq(200)

Expand All @@ -109,7 +110,7 @@
end

it 'should return a list filtered by category' do
get "/docs.json?category=#{category2.id}"
get "/#{GlobalSetting.docs_path}.json?category=#{category2.id}"

expect(response.status).to eq(200)

Expand All @@ -122,7 +123,7 @@
end

it 'ignores category filter when incorrect argument' do
get "/docs.json?category=hack"
get "/#{GlobalSetting.docs_path}.json?category=hack"

expect(response.status).to eq(200)

Expand All @@ -139,7 +140,7 @@
context 'when ordering results' do
describe 'by title' do
it 'should return the list ordered descending' do
get "/docs.json?order=title"
get "/#{GlobalSetting.docs_path}.json?order=title"

expect(response.status).to eq(200)

Expand All @@ -151,7 +152,7 @@
end

it 'should return the list ordered ascending with an additional parameter' do
get "/docs.json?order=title&ascending=true"
get "/#{GlobalSetting.docs_path}.json?order=title&ascending=true"

expect(response.status).to eq(200)

Expand All @@ -169,7 +170,7 @@
end

it 'should return the list ordered descending' do
get "/docs.json?order=activity"
get "/#{GlobalSetting.docs_path}.json?order=activity"

expect(response.status).to eq(200)

Expand All @@ -181,7 +182,7 @@
end

it 'should return the list ordered ascending with an additional parameter' do
get "/docs.json?order=activity&ascending=true"
get "/#{GlobalSetting.docs_path}.json?order=activity&ascending=true"

expect(response.status).to eq(200)

Expand Down Expand Up @@ -211,7 +212,7 @@
end

it 'should correctly filter topics' do
get "/docs.json?search=banana"
get "/#{GlobalSetting.docs_path}.json?search=banana"

expect(response.status).to eq(200)

Expand All @@ -225,7 +226,7 @@

expect(topics.size).to eq(2)

get "/docs.json?search=walk"
get "/#{GlobalSetting.docs_path}.json?search=walk"

json = JSON.parse(response.body)
topics = json['topics']['topic_list']['topics']
Expand All @@ -239,29 +240,29 @@
let!(:non_ke_topic) { Fabricate(:topic) }

it 'should correctly grab the topic' do
get "/docs.json?topic=#{topic.id}"
get "/#{GlobalSetting.docs_path}.json?topic=#{topic.id}"

expect(response.parsed_body['topic']['id']).to eq(topic.id)
end

it 'should get topics matching a selected docs tag or category' do
get "/docs.json?topic=#{non_ke_topic.id}"
get "/#{GlobalSetting.docs_path}.json?topic=#{non_ke_topic.id}"

expect(response.parsed_body['topic']).to be_blank
end

it 'should return a docs topic when only tags are added to settings' do
SiteSetting.docs_categories = nil

get "/docs.json?topic=#{topic.id}"
get "/#{GlobalSetting.docs_path}.json?topic=#{topic.id}"

expect(response.parsed_body['topic']['id']).to eq(topic.id)
end

it 'should return a docs topic when only categories are added to settings' do
SiteSetting.docs_tags = nil

get "/docs.json?topic=#{topic.id}"
get "/#{GlobalSetting.docs_path}.json?topic=#{topic.id}"

expect(response.parsed_body['topic']['id']).to eq(topic.id)
end
Expand All @@ -270,19 +271,19 @@
admin = Fabricate(:admin)
sign_in(admin)
expect do
get "/docs.json?topic=#{topic.id}"
get "/#{GlobalSetting.docs_path}.json?topic=#{topic.id}"
end.to change { TopicViewItem.count }.by(1)
end

it 'should create TopicUser if authenticated' do
expect do
get "/docs.json?topic=#{topic.id}&track_visit=true"
get "/#{GlobalSetting.docs_path}.json?topic=#{topic.id}&track_visit=true"
end.not_to change { TopicUser.count }

admin = Fabricate(:admin)
sign_in(admin)
expect do
get "/docs.json?topic=#{topic.id}&track_visit=true"
get "/#{GlobalSetting.docs_path}.json?topic=#{topic.id}&track_visit=true"
end.to change { TopicUser.count }.by(1)
end
end
Expand Down
3 changes: 2 additions & 1 deletion spec/requests/robots_txt_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
describe RobotsTxtController do
before do
SiteSetting.docs_enabled = true
GlobalSetting.stubs(:docs_path).returns('docs')
end

it 'adds /docs/ to robots.txt' do
get '/robots.txt'

expect(response.body).to include('User-agent: *')
expect(response.body).to include('Disallow: /docs/')
expect(response.body).to include("Disallow: /#{GlobalSetting.docs_path}/")
end
end
26 changes: 26 additions & 0 deletions spec/serializers/site_serializer_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# frozen_string_literal: true

require 'rails_helper'

describe SiteSerializer do
fab!(:user) { Fabricate(:user) }
let(:guardian) { Guardian.new(user) }

before do
SiteSetting.docs_enabled = true
GlobalSetting.stubs(:docs_path).returns('docs')
end

it 'returns correct default value' do
data = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json

expect(data[:docs_path]).to eq("docs")
end

it 'returns custom path based on global setting' do
GlobalSetting.stubs(:docs_path).returns('custom_path')
data = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json

expect(data[:docs_path]).to eq("custom_path")
end
end

0 comments on commit 6b3f257

Please sign in to comment.