Can edit settings on the embedding page
This commit is contained in:
parent
d1c69189f3
commit
146f2eab7f
|
@ -0,0 +1,23 @@
|
|||
import computed from 'ember-addons/ember-computed-decorators';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
classNames: ['embed-setting'],
|
||||
|
||||
@computed('field')
|
||||
inputId(field) { return field.dasherize(); },
|
||||
|
||||
@computed('field')
|
||||
translationKey(field) { return `admin.embedding.${field}`; },
|
||||
|
||||
@computed('type')
|
||||
isCheckbox(type) { return type === "checkbox"; },
|
||||
|
||||
@computed('value')
|
||||
checked: {
|
||||
get(value) { return !!value; },
|
||||
set(value) {
|
||||
this.set('value', value);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
});
|
|
@ -0,0 +1,12 @@
|
|||
import { on, observes } from 'ember-addons/ember-computed-decorators';
|
||||
import highlightSyntax from 'discourse/lib/highlight-syntax';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
|
||||
@on('didInsertElement')
|
||||
@observes('code')
|
||||
_refresh: function() {
|
||||
highlightSyntax(this.$());
|
||||
}
|
||||
|
||||
});
|
|
@ -1,9 +1,46 @@
|
|||
import computed from 'ember-addons/ember-computed-decorators';
|
||||
import { popupAjaxError } from 'discourse/lib/ajax-error';
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
saved: false,
|
||||
embedding: null,
|
||||
|
||||
// show settings if we have at least one created host
|
||||
@computed('embedding.embeddable_hosts.@each.isCreated')
|
||||
showSecondary() {
|
||||
const hosts = this.get('embedding.embeddable_hosts');
|
||||
return hosts.length && hosts.findProperty('isCreated');
|
||||
},
|
||||
|
||||
@computed('embedding.base_url')
|
||||
embeddingCode(baseUrl) {
|
||||
|
||||
const html =
|
||||
`<div id='discourse-comments'></div>
|
||||
|
||||
<script type="text/javascript">
|
||||
DiscourseEmbed = { discourseUrl: '${baseUrl}/',
|
||||
discourseEmbedUrl: 'REPLACE_ME' };
|
||||
|
||||
(function() {
|
||||
var d = document.createElement('script'); d.type = 'text/javascript'; d.async = true;
|
||||
d.src = DiscourseEmbed.discourseUrl + 'javascripts/embed.js';
|
||||
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(d);
|
||||
})();
|
||||
</script>`;
|
||||
|
||||
return html;
|
||||
},
|
||||
|
||||
actions: {
|
||||
saveChanges() {
|
||||
this.get('embedding').update({});
|
||||
const embedding = this.get('embedding');
|
||||
const updates = embedding.getProperties(embedding.get('fields'));
|
||||
|
||||
this.set('saved', false);
|
||||
this.get('embedding').update(updates).then(() => {
|
||||
this.set('saved', true);
|
||||
}).catch(popupAjaxError);
|
||||
},
|
||||
|
||||
addHost() {
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
{{#if isCheckbox}}
|
||||
<label for={{inputId}}>
|
||||
{{input checked=checked id=inputId type="checkbox"}}
|
||||
{{i18n translationKey}}
|
||||
</label>
|
||||
{{else}}
|
||||
<label for={{inputId}}>{{i18n translationKey}}</label>
|
||||
{{input value=value id=inputId}}
|
||||
{{/if}}
|
||||
|
||||
<div class='clearfix'></div>
|
|
@ -0,0 +1 @@
|
|||
<pre><code class={{lang}}>{{code}}</code></pre>
|
|
@ -1,15 +1,61 @@
|
|||
{{#if embedding.embeddable_hosts}}
|
||||
<table>
|
||||
<tr>
|
||||
<th style='width: 50%'>{{i18n "admin.embedding.host"}}</th>
|
||||
<th style='width: 30%'>{{i18n "admin.embedding.category"}}</th>
|
||||
<th style='width: 20%'> </th>
|
||||
</tr>
|
||||
{{#each embedding.embeddable_hosts as |host|}}
|
||||
{{embeddable-host host=host deleteHost="deleteHost"}}
|
||||
{{/each}}
|
||||
</table>
|
||||
<div class='embeddable-hosts'>
|
||||
{{#if embedding.embeddable_hosts}}
|
||||
<table class='embedding'>
|
||||
<tr>
|
||||
<th style='width: 50%'>{{i18n "admin.embedding.host"}}</th>
|
||||
<th style='width: 30%'>{{i18n "admin.embedding.category"}}</th>
|
||||
<th style='width: 20%'> </th>
|
||||
</tr>
|
||||
{{#each embedding.embeddable_hosts as |host|}}
|
||||
{{embeddable-host host=host deleteHost="deleteHost"}}
|
||||
{{/each}}
|
||||
</table>
|
||||
{{else}}
|
||||
<p>{{i18n "admin.embedding.get_started"}}</p>
|
||||
{{/if}}
|
||||
|
||||
{{d-button label="admin.embedding.add_host" action="addHost" icon="plus" class="btn-primary add-host"}}
|
||||
</div>
|
||||
|
||||
{{#if showSecondary}}
|
||||
<div class='embedding-secondary'>
|
||||
<p>{{{i18n "admin.embedding.sample"}}}</p>
|
||||
{{highlighted-code code=embeddingCode lang="html"}}
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class='embedding-secondary'>
|
||||
<h3>{{i18n "admin.embedding.settings"}}</h3>
|
||||
|
||||
{{embedding-setting field="embed_by_username" value=embedding.embed_by_username}}
|
||||
{{embedding-setting field="embed_post_limit" value=embedding.embed_post_limit}}
|
||||
{{embedding-setting field="embed_truncate" value=embedding.embed_truncate type="checkbox"}}
|
||||
</div>
|
||||
|
||||
<div class='embedding-secondary'>
|
||||
<h3>{{i18n "admin.embedding.feed_settings"}}</h3>
|
||||
<p class="description">{{i18n "admin.embedding.feed_description"}}</p>
|
||||
|
||||
{{embedding-setting field="feed_polling_enabled" value=embedding.feed_polling_enabled type="checkbox"}}
|
||||
{{embedding-setting field="feed_polling_url" value=embedding.feed_polling_url}}
|
||||
{{embedding-setting field="embed_username_key_from_feed" value=embedding.embed_username_key_from_feed}}
|
||||
</div>
|
||||
|
||||
<div class='embedding-secondary'>
|
||||
<h3>{{i18n "admin.embedding.crawling_settings"}}</h3>
|
||||
<p class="description">{{i18n "admin.embedding.crawling_description"}}</p>
|
||||
|
||||
{{embedding-setting field="embed_whitelist_selector" value=embedding.embed_whitelist_selector}}
|
||||
{{embedding-setting field="embed_blacklist_selector" value=embedding.embed_blacklist_selector}}
|
||||
</div>
|
||||
|
||||
<div class='embedding-secondary'>
|
||||
{{d-button label="admin.embedding.save"
|
||||
action="saveChanges"
|
||||
class="btn-primary embed-save"
|
||||
disabled=embedding.isSaving}}
|
||||
|
||||
{{#if saved}}{{i18n "saved"}}{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{d-button label="admin.embedding.add_host" action="addHost" icon="plus" class="btn-primary"}}
|
||||
|
||||
|
|
|
@ -1648,6 +1648,36 @@ table#user-badges {
|
|||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
|
||||
// embedding
|
||||
|
||||
.embeddable-hosts {
|
||||
table {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
.embedding-secondary {
|
||||
h3 {
|
||||
margin: 1em 0;
|
||||
}
|
||||
margin-bottom: 2em;
|
||||
|
||||
.embed-setting {
|
||||
input[type=text] {
|
||||
width: 50%;
|
||||
}
|
||||
margin: 0.75em 0;
|
||||
}
|
||||
|
||||
p.description {
|
||||
color: dark-light-choose(scale-color($primary, $lightness: 50%), scale-color($secondary, $lightness: 50%));
|
||||
margin-bottom: 1em;
|
||||
max-width: 700px;
|
||||
}
|
||||
}
|
||||
|
||||
// Mobile specific styles
|
||||
// Mobile view text-inputs need some padding
|
||||
.mobile-view .admin-contents {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
require_dependency 'embedding'
|
||||
|
||||
class Admin::EmbeddingController < Admin::AdminController
|
||||
|
||||
before_filter :ensure_logged_in, :ensure_staff, :fetch_embedding
|
||||
|
@ -7,15 +9,21 @@ class Admin::EmbeddingController < Admin::AdminController
|
|||
end
|
||||
|
||||
def update
|
||||
render_serialized(@embedding, EmbeddingSerializer, root: 'embedding', rest_serializer: true)
|
||||
Embedding.settings.each do |s|
|
||||
@embedding.send("#{s}=", params[:embedding][s])
|
||||
end
|
||||
|
||||
if @embedding.save
|
||||
fetch_embedding
|
||||
render_serialized(@embedding, EmbeddingSerializer, root: 'embedding', rest_serializer: true)
|
||||
else
|
||||
render_json_error(@embedding)
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def fetch_embedding
|
||||
@embedding = OpenStruct.new({
|
||||
id: 'default',
|
||||
embeddable_hosts: EmbeddableHost.all.order(:host)
|
||||
})
|
||||
@embedding = Embedding.find
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
require 'has_errors'
|
||||
|
||||
class Embedding < OpenStruct
|
||||
include HasErrors
|
||||
|
||||
def self.settings
|
||||
%i(embed_by_username
|
||||
embed_post_limit
|
||||
embed_truncate
|
||||
embed_whitelist_selector
|
||||
embed_blacklist_selector
|
||||
feed_polling_enabled
|
||||
feed_polling_url
|
||||
embed_username_key_from_feed)
|
||||
end
|
||||
|
||||
def base_url
|
||||
Discourse.base_url
|
||||
end
|
||||
|
||||
def save
|
||||
Embedding.settings.each do |s|
|
||||
SiteSetting.send("#{s}=", send(s))
|
||||
end
|
||||
true
|
||||
rescue Discourse::InvalidParameters => p
|
||||
errors.add :base, p.to_s
|
||||
false
|
||||
end
|
||||
|
||||
def embeddable_hosts
|
||||
EmbeddableHost.all.order(:host)
|
||||
end
|
||||
|
||||
def self.find
|
||||
embedding_args = { id: 'default' }
|
||||
|
||||
Embedding.settings.each {|s| embedding_args[s] = SiteSetting.send(s) }
|
||||
Embedding.new(embedding_args)
|
||||
end
|
||||
end
|
|
@ -1,8 +1,14 @@
|
|||
class EmbeddingSerializer < ApplicationSerializer
|
||||
attributes :id
|
||||
attributes :id, :fields, :base_url
|
||||
attributes *Embedding.settings
|
||||
|
||||
has_many :embeddable_hosts, serializer: EmbeddableHostSerializer, embed: :ids
|
||||
|
||||
def id
|
||||
object.id
|
||||
def fields
|
||||
Embedding.settings
|
||||
end
|
||||
|
||||
def read_attribute_for_serialization(attr)
|
||||
object.respond_to?(attr) ? object.send(attr) : send(attr)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2492,12 +2492,29 @@ en:
|
|||
delete_confirm: "Are you sure you want to delete the :%{name}: emoji?"
|
||||
|
||||
embedding:
|
||||
get_started: "If you'd like to embed Discourse on another website, begin by adding its host."
|
||||
confirm_delete: "Are you sure you want to delete that host?"
|
||||
sample: "Use the following HTML code into your site to create and embed discourse topics. Replace <b>REPLACE_ME</b> with the canonical URL of the page you are embedding it on."
|
||||
title: "Embedding"
|
||||
host: "Allowed Hosts"
|
||||
edit: "edit"
|
||||
category: "Post to Category"
|
||||
add_host: "Add Host"
|
||||
settings: "Embedding Settings"
|
||||
feed_settings: "Feed Settings"
|
||||
feed_description: "Providing an RSS/ATOM feed for your site can improve Discourse's ability to import your content."
|
||||
crawling_settings: "Crawler Settings"
|
||||
crawling_description: "When Discourse creates topics for your posts, if no RSS/ATOM feed is present it will attempt to parse your content out of your HTML. Sometimes it can be challenging to extract your content, so we provide the ability to specify CSS rules to make extraction easier."
|
||||
|
||||
embed_by_username: "Username for topic creation"
|
||||
embed_post_limit: "Maximum number of posts to embed"
|
||||
embed_username_key_from_feed: "Key to pull discourse username from feed"
|
||||
embed_truncate: "Truncate the embedded posts"
|
||||
embed_whitelist_selector: "CSS selector for elements that are allowed in embeds"
|
||||
embed_blacklist_selector: "CSS selector for elements that are removed from embeds"
|
||||
feed_polling_enabled: "Import posts via RSS/ATOM"
|
||||
feed_polling_url: "URL of RSS/ATOM feed to crawl"
|
||||
save: "Save Embedding Settings"
|
||||
|
||||
permalink:
|
||||
title: "Permalinks"
|
||||
|
|
|
@ -759,16 +759,31 @@ developer:
|
|||
default: false
|
||||
|
||||
embedding:
|
||||
feed_polling_enabled: false
|
||||
feed_polling_url: ''
|
||||
feed_polling_enabled:
|
||||
default: false
|
||||
hidden: true
|
||||
feed_polling_url:
|
||||
default: ''
|
||||
hidden: true
|
||||
embed_by_username:
|
||||
default: ''
|
||||
type: username
|
||||
embed_username_key_from_feed: ''
|
||||
embed_post_limit: 100
|
||||
embed_truncate: false
|
||||
embed_whitelist_selector: ''
|
||||
embed_blacklist_selector: ''
|
||||
hidden: true
|
||||
embed_username_key_from_feed:
|
||||
default: ''
|
||||
hidden: true
|
||||
embed_post_limit:
|
||||
default: 100
|
||||
hidden: true
|
||||
embed_truncate:
|
||||
default: false
|
||||
hidden: true
|
||||
embed_whitelist_selector:
|
||||
default: ''
|
||||
hidden: true
|
||||
embed_blacklist_selector:
|
||||
default: ''
|
||||
hidden: true
|
||||
|
||||
legal:
|
||||
tos_url:
|
||||
|
|
Loading…
Reference in New Issue