├── README.md ├── app ├── controllers │ └── static_pages │ │ ├── admin_pages_controller.rb │ │ └── pages_controller.rb └── models │ └── static_pages │ └── page.rb ├── assets ├── javascripts │ ├── admin │ │ └── models │ │ │ └── page.js.es6 │ └── discourse │ │ ├── admin-pages-route-map.js.es6 │ │ ├── controllers │ │ └── admin-plugins-pages-index.js.es6 │ │ ├── initializers │ │ └── static-pages-menu.js.es6 │ │ ├── models │ │ └── page.js.es6 │ │ ├── pages-route-map.js.es6 │ │ ├── routes │ │ ├── admin-plugins-pages-edit.js.es6 │ │ ├── admin-plugins-pages-index.js.es6 │ │ ├── admin-plugins-pages-new.js.es6 │ │ └── pages-show.js.es6 │ │ └── templates │ │ ├── admin │ │ ├── plugins-pages-edit.hbs │ │ ├── plugins-pages-form.hbs │ │ ├── plugins-pages-index.hbs │ │ ├── plugins-pages-new.hbs │ │ └── plugins-pages.hbs │ │ ├── connectors │ │ └── site-map-links │ │ │ └── static-pages.hbs │ │ └── pages │ │ └── show.hbs └── stylesheets │ └── static_pages.scss ├── config ├── locales │ ├── client.en.yml │ └── server.en.yml ├── routes.rb └── settings.yml ├── db └── migrate │ └── 20151005185946_create_pages.rb ├── lib ├── pages.rb └── pages │ └── engine.rb └── plugin.rb /README.md: -------------------------------------------------------------------------------- 1 | # discourse-static-pages 2 | 3 | Static pages plugin for Discourse 4 | 5 | ## Installation 6 | 7 | Follow the Discourse plugin [installation guide](https://meta.discourse.org/t/install-a-plugin/19157) using `git clone https://github.com/nukomeet/discourse-static-pages.git`. 8 | 9 | ## Development 10 | 11 | ``` 12 | cd plugins 13 | git clone https://github.com/nukomeet/discourse-static-pages.git 14 | ``` 15 | -------------------------------------------------------------------------------- /app/controllers/static_pages/admin_pages_controller.rb: -------------------------------------------------------------------------------- 1 | module StaticPages 2 | class AdminPagesController < Admin::AdminController 3 | requires_plugin 'static-pages' 4 | 5 | def index 6 | render_json_dump(pages: Page.all) 7 | end 8 | 9 | def create 10 | page = Page.new(page_params) 11 | page.save! 12 | render_json_dump(page: page) 13 | end 14 | 15 | def show 16 | page = Page.find(params[:id]) 17 | render_json_dump(page: page) 18 | end 19 | 20 | def update 21 | page = Page.find(params[:id]) 22 | page.update_attributes!(page_params) 23 | render_json_dump(page: page) 24 | end 25 | 26 | def destroy 27 | page = Page.find(params[:id]) 28 | page.delete 29 | render nothing: true, status: 204 30 | end 31 | 32 | private 33 | 34 | def page_params 35 | params.require(:page).permit(:title, :body) 36 | end 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /app/controllers/static_pages/pages_controller.rb: -------------------------------------------------------------------------------- 1 | module StaticPages 2 | class PagesController < ApplicationController 3 | def index 4 | render_json_dump(pages: Page.all) 5 | end 6 | 7 | def show 8 | page = Page.find(params[:id]) 9 | render_json_dump(page: page) 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /app/models/static_pages/page.rb: -------------------------------------------------------------------------------- 1 | module StaticPages 2 | class Page < ActiveRecord::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /assets/javascripts/admin/models/page.js.es6: -------------------------------------------------------------------------------- 1 | export default { 2 | findAll() { 3 | return Discourse.ajax('/pages/admin/pages'); 4 | }, 5 | 6 | findById(id) { 7 | return Discourse.ajax(`/pages/admin/pages/${id}`); 8 | }, 9 | 10 | create(model) { 11 | return Discourse.ajax('/pages/admin/pages', { 12 | method: 'POST', 13 | contentType: 'application/json', 14 | data: JSON.stringify({ page: model }) 15 | }); 16 | }, 17 | 18 | update(model) { 19 | return Discourse.ajax(`/pages/admin/pages/${model.id}`, { 20 | method: 'PATCH', 21 | contentType: 'application/json', 22 | data: JSON.stringify({ page: model }) 23 | }) 24 | }, 25 | 26 | delete(model) { 27 | return Discourse.ajax(`/pages/admin/pages/${model.id}`, { 28 | method: 'DELETE' 29 | }); 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/admin-pages-route-map.js.es6: -------------------------------------------------------------------------------- 1 | export default { 2 | resource: 'admin.adminPlugins', 3 | path: '/plugins', 4 | map() { 5 | this.route('pages', function () { 6 | this.route('new'); 7 | this.route('edit', { path: ':id/edit' }); 8 | }); 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/controllers/admin-plugins-pages-index.js.es6: -------------------------------------------------------------------------------- 1 | import Page from '../../admin/models/page'; 2 | 3 | export default Ember.ArrayController.extend({ 4 | sortProperties: ['updated_at'], 5 | sortAscending: false, 6 | 7 | actions: { 8 | refresh() { 9 | Page.findAll() 10 | .then((result) => { 11 | this.set('model', result.pages); 12 | }); 13 | }, 14 | 15 | delete(model) { 16 | if (confirm('Are you sure?')) { 17 | this.set('model', this.get('model').filter((page) => page !== model)); 18 | Page.delete(model); 19 | } 20 | } 21 | } 22 | }); 23 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/initializers/static-pages-menu.js.es6: -------------------------------------------------------------------------------- 1 | import HamburgerMenuComponent from 'discourse/components/hamburger-menu'; 2 | import Page from '../../discourse/models/page'; 3 | 4 | export default { 5 | name: 'static-pages-menu', 6 | 7 | initialize: function() { 8 | HamburgerMenuComponent.reopen({ 9 | didInsertElement() { 10 | Page.findAll() 11 | .then((result) => { 12 | this.set('staticPages', result.pages); 13 | }); 14 | 15 | this.set('staticPages', [{ title: 'Testing', id: 123 }]); 16 | } 17 | }); 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/models/page.js.es6: -------------------------------------------------------------------------------- 1 | export default { 2 | findAll() { 3 | return Discourse.ajax('/pages'); 4 | }, 5 | 6 | findById(id) { 7 | return Discourse.ajax(`/pages/${id}`); 8 | } 9 | }; 10 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/pages-route-map.js.es6: -------------------------------------------------------------------------------- 1 | export default { 2 | resource: 'pages', 3 | path: '/pages', 4 | map() { 5 | this.route('show', { path: ':id' }); 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/routes/admin-plugins-pages-edit.js.es6: -------------------------------------------------------------------------------- 1 | import Page from '../../admin/models/page'; 2 | 3 | export default Discourse.Route.extend({ 4 | actions: { 5 | update() { 6 | const { id, title, body } = this.controller.model; 7 | 8 | Page.update({ id, title, body }) 9 | .then(() => { 10 | this.transitionTo('adminPlugins.pages.index'); 11 | }) 12 | .catch(() => { 13 | alert('Error updating page.'); 14 | }); 15 | }, 16 | 17 | cancel() { 18 | this.transitionTo('adminPlugins.pages.index'); 19 | } 20 | }, 21 | 22 | model(params) { 23 | return Page.findById(params.id).then((result) => { 24 | return result.page; 25 | }); 26 | } 27 | }); 28 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/routes/admin-plugins-pages-index.js.es6: -------------------------------------------------------------------------------- 1 | import Page from '../../admin/models/page'; 2 | 3 | export default Discourse.Route.extend({ 4 | model() { 5 | return Page.findAll().then((result) => { 6 | return result.pages; 7 | }); 8 | }, 9 | 10 | setupController(controller, model) { 11 | controller.setProperties({ model }); 12 | } 13 | }); 14 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/routes/admin-plugins-pages-new.js.es6: -------------------------------------------------------------------------------- 1 | import Page from '../../admin/models/page'; 2 | 3 | export default Discourse.Route.extend({ 4 | actions: { 5 | create() { 6 | const { title, body } = this.controller.model; 7 | 8 | Page.create({ title, body }) 9 | .then(() => { 10 | this.transitionTo('adminPlugins.pages.index'); 11 | }) 12 | .catch(() => { 13 | alert('Error creating page.'); 14 | }); 15 | }, 16 | 17 | cancel() { 18 | this.transitionTo('adminPlugins.pages.index'); 19 | } 20 | }, 21 | 22 | model() { 23 | return {}; 24 | } 25 | }); 26 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/routes/pages-show.js.es6: -------------------------------------------------------------------------------- 1 | import Page from '../models/page'; 2 | 3 | export default Discourse.Route.extend({ 4 | model(params) { 5 | return Page.findById(params.id).then((result) => { 6 | return result.page; 7 | }); 8 | }, 9 | 10 | setupController(controller, model) { 11 | model.body = new Handlebars.SafeString(Discourse.Markdown.cook(model.body)); 12 | controller.setProperties({ model }); 13 | } 14 | }); 15 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/templates/admin/plugins-pages-edit.hbs: -------------------------------------------------------------------------------- 1 |
2 | {{partial 'admin/plugins-pages-form'}} 3 | 4 |
5 | 6 |
7 | 8 | 11 |
12 |
13 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/templates/admin/plugins-pages-form.hbs: -------------------------------------------------------------------------------- 1 |
2 | 5 |
6 | {{input type="text" name="title" value=model.title required="true"}} 7 |
8 |
9 |
10 | 13 |
14 | {{d-editor name="body" value=model.body required="true"}} 15 |
16 |
17 | 18 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/templates/admin/plugins-pages-index.hbs: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | {{#each page in model}} 13 | 14 | 17 | 20 | 23 | 28 | 29 | {{/each}} 30 | 31 |
{{i18n 'static_pages.page'}}{{i18n 'static_pages.created'}}{{i18n 'static_pages.updated'}}{{i18n 'static_pages.actions'}}
15 | {{page.title}} 16 | 18 | {{page.created_at}} 19 | 21 | {{page.updated_at}} 22 | 24 | {{#link-to 'pages.show' page.id class="btn"}}{{i18n 'static_pages.view'}}{{/link-to}} 25 | {{#link-to 'adminPlugins.pages.edit' page.id class="btn btn-primary"}}{{i18n 'static_pages.edit'}}{{/link-to}} 26 | 27 |
32 |
33 | 34 |
35 | {{#link-to 'adminPlugins.pages.new' class="btn btn-primary"}}{{i18n 'static_pages.new'}}{{/link-to}} 36 | 37 |
38 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/templates/admin/plugins-pages-new.hbs: -------------------------------------------------------------------------------- 1 |
2 | {{partial 'admin/plugins-pages-form'}} 3 | 4 |
5 | 6 |
7 | 8 | 11 |
12 |
13 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/templates/admin/plugins-pages.hbs: -------------------------------------------------------------------------------- 1 | {{outlet}} 2 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/templates/connectors/site-map-links/static-pages.hbs: -------------------------------------------------------------------------------- 1 | {{#each staticPages as |page|}} 2 |
  • 3 | {{#link-to 'pages.show' page.id}}{{page.title}}{{/link-to}} 4 |
  • 5 | {{/each}} 6 | -------------------------------------------------------------------------------- /assets/javascripts/discourse/templates/pages/show.hbs: -------------------------------------------------------------------------------- 1 |
    2 |

    {{model.title}}

    3 | 4 | {{model.body}} 5 |
    6 | -------------------------------------------------------------------------------- /assets/stylesheets/static_pages.scss: -------------------------------------------------------------------------------- 1 | body .wmd-input { 2 | height: 250px; 3 | width: 98%; 4 | } 5 | 6 | .static-page { 7 | line-height: 2em; 8 | 9 | h1, h2, h3, h4, h5, h6 { 10 | margin-bottom: 0.5em; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /config/locales/client.en.yml: -------------------------------------------------------------------------------- 1 | en: 2 | js: 3 | static_pages: 4 | pages: 'Pages' 5 | refresh: 'Refresh' 6 | new: 'New' 7 | view: 'View' 8 | edit: 'Edit' 9 | create: 'Create' 10 | update: 'Update' 11 | delete: 'Delete' 12 | cancel: 'Cancel' 13 | page: 'Page' 14 | created: 'Created' 15 | updated: 'Updated' 16 | actions: 'Actions' 17 | title: 'Title' 18 | body: 'Body' 19 | -------------------------------------------------------------------------------- /config/locales/server.en.yml: -------------------------------------------------------------------------------- 1 | en: 2 | site_settings: 3 | static_pages_enabled: 'Static pages enabled?' 4 | -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | StaticPages::Engine.routes.draw do 2 | 3 | # TODO: Why doesn't resource work as expected here? 4 | # Does Rails not know it's a model resource since the 5 | # model is namespaced? 6 | 7 | resource :admin_pages, path: '/admin/pages', constraints: AdminConstraint.new, only: [] do 8 | collection do 9 | get '' => 'admin_pages#index' 10 | post '' => 'admin_pages#create' 11 | end 12 | 13 | member do 14 | get ':id' => 'admin_pages#show' 15 | patch ':id' => 'admin_pages#update' 16 | delete ':id' => 'admin_pages#destroy' 17 | end 18 | end 19 | 20 | class PagesEnabledConstraint 21 | def matches?(request) 22 | SiteSetting.static_pages_enabled 23 | end 24 | end 25 | 26 | resource :pages, path: '', constraints: PagesEnabledConstraint.new, only: [] do 27 | collection do 28 | get '' => 'pages#index' 29 | end 30 | 31 | member do 32 | get ':id' => 'pages#show' 33 | end 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /config/settings.yml: -------------------------------------------------------------------------------- 1 | plugins: 2 | static_pages_enabled: 3 | default: true 4 | client: true 5 | -------------------------------------------------------------------------------- /db/migrate/20151005185946_create_pages.rb: -------------------------------------------------------------------------------- 1 | class CreatePages < ActiveRecord::Migration 2 | def change 3 | create_table :static_pages_pages do |t| 4 | t.string :title, null: false 5 | t.text :body, null: false 6 | t.timestamps 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /lib/pages.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../pages/engine', __FILE__) 2 | 3 | module StaticPages 4 | end 5 | -------------------------------------------------------------------------------- /lib/pages/engine.rb: -------------------------------------------------------------------------------- 1 | module StaticPages 2 | class Engine < ::Rails::Engine 3 | isolate_namespace StaticPages 4 | 5 | config.after_initialize do 6 | Discourse::Application.routes.append do 7 | mount StaticPages::Engine, at: '/pages' 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /plugin.rb: -------------------------------------------------------------------------------- 1 | # name: static-pages 2 | # about: Static pages plugin for Discourse 3 | # version: 0.0.1 4 | # authors: Nukomeet 5 | 6 | enabled_site_setting :static_pages_enabled 7 | add_admin_route 'static_pages.pages', 'pages' 8 | register_asset 'stylesheets/static_pages.scss' 9 | 10 | Discourse::Application.routes.append do 11 | get '/admin/plugins/pages' => 'admin/plugins#index', constraints: AdminConstraint.new 12 | get '/admin/plugins/pages/new' => 'admin/plugins#index', constraints: AdminConstraint.new 13 | get '/admin/plugins/pages/:id/edit' => 'admin/plugins#index', constraints: AdminConstraint.new 14 | end 15 | 16 | load File.expand_path('../lib/pages.rb', __FILE__) 17 | --------------------------------------------------------------------------------