mirror of
https://git.friendi.ca/friendica/friendica-addons.git
synced 2024-11-22 10:43:40 +00:00
Merge pull request #684 from MrPetovan/bug/5341-advancedcontentfilter-honors-csp
Advancedcontentfilter honors CSP (redux)
This commit is contained in:
commit
ce97e09126
4 changed files with 199 additions and 194 deletions
132
advancedcontentfilter/advancedcontentfilter.js
Normal file
132
advancedcontentfilter/advancedcontentfilter.js
Normal file
File diff suppressed because one or more lines are too long
|
@ -170,7 +170,7 @@ function advancedcontentfilter_module() {}
|
|||
|
||||
function advancedcontentfilter_init(App $a)
|
||||
{
|
||||
if ($a->argv[1] == 'api') {
|
||||
if ($a->argc > 1 && $a->argv[1] == 'api') {
|
||||
$slim = new \Slim\App();
|
||||
|
||||
require __DIR__ . '/src/middlewares.php';
|
||||
|
@ -188,7 +188,7 @@ function advancedcontentfilter_content(App $a)
|
|||
return Login::form('/' . implode('/', $a->argv));
|
||||
}
|
||||
|
||||
if ($a->argc > 0 && $a->argv[1] == 'help') {
|
||||
if ($a->argc > 1 && $a->argv[1] == 'help') {
|
||||
$lang = $a->user['language'];
|
||||
|
||||
$default_dir = 'addon/advancedcontentfilter/doc/';
|
||||
|
@ -208,31 +208,31 @@ function advancedcontentfilter_content(App $a)
|
|||
} else {
|
||||
$t = get_markup_template('settings.tpl', 'addon/advancedcontentfilter/');
|
||||
return replace_macros($t, [
|
||||
'$messages' => [
|
||||
'backtosettings' => L10n::t('Back to Addon Settings'),
|
||||
'title' => L10n::t('Advanced Content Filter'),
|
||||
'add_a_rule' => L10n::t('Add a Rule'),
|
||||
'help' => L10n::t('Help'),
|
||||
'intro' => L10n::t('Add and manage your personal content filter rules in this screen. Rules have a name and an arbitrary expression that will be matched against post data. For a complete reference of the available operations and variables, check the help page.'),
|
||||
'your_rules' => L10n::t('Your rules'),
|
||||
'no_rules' => L10n::t('You have no rules yet! Start adding one by clicking on the button above next to the title.'),
|
||||
'disabled' => L10n::t('Disabled'),
|
||||
'enabled' => L10n::t('Enabled'),
|
||||
'disable_this_rule' => L10n::t('Disable this rule'),
|
||||
'enable_this_rule' => L10n::t('Enable this rule'),
|
||||
'edit_this_rule' => L10n::t('Edit this rule'),
|
||||
'edit_the_rule' => L10n::t('Edit the rule'),
|
||||
'save_this_rule' => L10n::t('Save this rule'),
|
||||
'delete_this_rule' => L10n::t('Delete this rule'),
|
||||
'rule' => L10n::t('Rule'),
|
||||
'close' => L10n::t('Close'),
|
||||
'addtitle' => L10n::t('Add new rule'),
|
||||
'rule_name' => L10n::t('Rule Name'),
|
||||
'rule_expression' => L10n::t('Rule Expression'),
|
||||
'cancel' => L10n::t('Cancel'),
|
||||
],
|
||||
'$current_theme' => $a->getCurrentTheme(),
|
||||
'$backtosettings' => L10n::t('Back to Addon Settings'),
|
||||
'$title' => L10n::t('Advanced Content Filter'),
|
||||
'$add_a_rule' => L10n::t('Add a Rule'),
|
||||
'$help' => L10n::t('Help'),
|
||||
'$advanced_content_filter_intro' => addslashes(L10n::t('Add and manage your personal content filter rules in this screen. Rules have a name and an arbitrary expression that will be matched against post data. For a complete reference of the available operations and variables, check the <a href="advancedcontentfilter/help">help page</a>.')),
|
||||
'$your_rules' => L10n::t('Your rules'),
|
||||
'$no_rules' => L10n::t('You have no rules yet! Start adding one by clicking on the button above next to the title.'),
|
||||
'$disabled' => L10n::t('Disabled'),
|
||||
'$enabled' => L10n::t('Enabled'),
|
||||
'$disable_this_rule' => L10n::t('Disable this rule'),
|
||||
'$enable_this_rule' => L10n::t('Enable this rule'),
|
||||
'$edit_this_rule' => L10n::t('Edit this rule'),
|
||||
'$edit_the_rule' => L10n::t('Edit the rule'),
|
||||
'$save_this_rule' => L10n::t('Save this rule'),
|
||||
'$delete_this_rule' => L10n::t('Delete this rule'),
|
||||
'$rule' => L10n::t('Rule'),
|
||||
'$close' => L10n::t('Close'),
|
||||
'$addtitle' => L10n::t('Add new rule'),
|
||||
'$rule_name' => L10n::t('Rule Name'),
|
||||
'$rule_expression' => L10n::t('Rule Expression'),
|
||||
'$examples' => L10n::t('<p>Examples:</p><ul><li><pre>author_link == \'https://friendica.mrpetovan.com/profile/hypolite\'</pre></li><li>tags</li></ul>'),
|
||||
'$cancel' => L10n::t('Cancel'),
|
||||
'$rules' => advancedcontentfilter_get_rules(),
|
||||
'$baseurl' => System::baseUrl(true),
|
||||
'$form_security_token' => get_form_security_token()
|
||||
]);
|
||||
}
|
||||
|
|
|
@ -1,51 +1,52 @@
|
|||
<!--
|
||||
This the the source HTML for the render functions defined in settings.tpl
|
||||
This the the source HTML for the render functions defined in advancedcontentfilter.js
|
||||
This file is only for reference only and editing it won't change the addon display.
|
||||
Here's the workflow to change the actual display:
|
||||
1. Edit this file
|
||||
2. Run it through https://vuejs.org/v2/guide/render-function.html#Template-Compilation
|
||||
3. In the results, replace ##$ by {{$ and ## by }} in order to restore smarty variable interpolation
|
||||
4. Replace the render and staticRenderFns members in settings.tpl by the contents of the output anonymous() functions
|
||||
3. Replace the render and staticRenderFns members in advancedcontentfilter.js by the contents of the anonymous() functions
|
||||
-->
|
||||
<div id="rules">
|
||||
<p><a href="settings/addon">🔙 ##$backtosettings##</a></p>
|
||||
<p><a href="settings/addon">🔙 {{ messages.backtosettings }}</a></p>
|
||||
<h1>
|
||||
##$title##
|
||||
|
||||
<a href="##$baseurl##/advancedcontentfilter/help" class="btn btn-default btn-sm" title="##$help##">
|
||||
{{ messages.title }}
|
||||
|
||||
<a href="advancedcontentfilter/help" class="btn btn-default btn-sm" :title="messages.help">
|
||||
<i class="fa fa-question fa-2x" aria-hidden="true"></i>
|
||||
</a>
|
||||
</h1>
|
||||
<div>##$advanced_content_filter_intro##</div>
|
||||
<div>{{ messages.intro }}</div>
|
||||
<h2>
|
||||
##$your_rules##
|
||||
<button class="btn btn-primary btn-sm" title="##$add_a_rule##" @click="showModal = true">
|
||||
{{ messages.your_rules }}
|
||||
|
||||
<button class="btn btn-primary btn-sm" :title="messages.add_a_rule" @click="showModal = true">
|
||||
<i class="fa fa-plus fa-2x" aria-hidden="true"></i>
|
||||
</button>
|
||||
</h2>
|
||||
<div v-if="rules.length === 0" v-cloak>
|
||||
##$no_rules##
|
||||
{{ messages.no_rules }}
|
||||
</div>
|
||||
|
||||
<ul class="list-group" v-cloak>
|
||||
<li class="list-group-item" v-for="rule in rules">
|
||||
<p class="pull-right">
|
||||
<button type="button" class="btn btn-xs btn-primary" v-on:click="toggleActive(rule)" aria-label="##$disable_this_rule##" title="##$disable_this_rule##" v-if="parseInt(rule.active)">
|
||||
<i class="fa fa-toggle-on" aria-hidden="true"></i> ##$enabled##
|
||||
<button type="button" class="btn btn-xs btn-primary" v-on:click="toggleActive(rule)" :aria-label="messages.disable_this_rule" :title="messages.disable_this_rule" v-if="parseInt(rule.active)">
|
||||
<i class="fa fa-toggle-on" aria-hidden="true"></i> {{ messages.enabled }}
|
||||
</button>
|
||||
<button type="button" class="btn btn-xs btn-default" v-on:click="toggleActive(rule)" aria-label="##$enable_this_rule##" title="##$enable_this_rule##" v-else>
|
||||
<i class="fa fa-toggle-off" aria-hidden="true"></i> ##$disabled##
|
||||
<button type="button" class="btn btn-xs btn-default" v-on:click="toggleActive(rule)" :aria-label="messages.enable_this_rule" :title="messages.enable_this_rule" v-else>
|
||||
<i class="fa fa-toggle-off" aria-hidden="true"></i> {{ messages.disabled }}
|
||||
</button>
|
||||
|
||||
<button type="button" class="btn btn-xs btn-primary" v-on:click="editRule(rule)" aria-label="##$edit_this_rule##" title="##$edit_this_rule##">
|
||||
|
||||
<button type="button" class="btn btn-xs btn-primary" v-on:click="editRule(rule)" :aria-label="messages.edit_this_rule" :title="messages.edit_this_rule">
|
||||
<i class="fa fa-pencil" aria-hidden="true"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-xs btn-default" v-on:click="deleteRule(rule)" aria-label="##$delete_this_rule##" title="##$delete_this_rule##">
|
||||
|
||||
<button type="button" class="btn btn-xs btn-default" v-on:click="deleteRule(rule)" :aria-label="messages.delete_this_rule" :title="messages.delete_this_rule">
|
||||
<i class="fa fa-trash-o" aria-hidden="true"></i>
|
||||
</button>
|
||||
</p>
|
||||
<h3 class="list-group-item-heading">
|
||||
##$rule## #{{ rule.id }}: {{ rule.name }}
|
||||
{{ messages.rule }} #{{ rule.id }}: {{ rule.name }}
|
||||
</h3>
|
||||
<pre class="list-group-item-text" v-if="rule.expression">{{ rule.expression }}</pre>
|
||||
</li>
|
||||
|
@ -55,26 +56,25 @@
|
|||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="##$close##" @click="showModal = false"><span aria-hidden="true">×</span></button>
|
||||
<h3 v-if="rule.id">##$edit_the_rule## "{{ rule.name }}"</h3>
|
||||
<h3 v-if="!rule.id">##$add_a_rule##</h3>
|
||||
<button type="button" class="close" data-dismiss="modal" :aria-label="messages.close" @click="showModal = false" v-if="currentTheme === 'frio'"><span aria-hidden="true">×</span></button>
|
||||
<h3 v-if="rule.id">{{ messages.edit_the_rule }} "{{ rule.name }}"</h3>
|
||||
<h3 v-if="!rule.id">{{ messages.add_a_rule }}</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form>
|
||||
<input type="hidden" name="form_security_token" id="csrf" value="##$form_security_token##" />
|
||||
<div class="alert alert-danger" role="alert" v-if="errorMessage">{{ errorMessage }}</div>
|
||||
<div class="form-group">
|
||||
<input class="form-control" placeholder="##$rule_name##" v-model="rule.name">
|
||||
<input class="form-control" :placeholder="messages.rule_name" v-model="rule.name">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input class="form-control" placeholder="##$rule_expression##" v-model="rule.expression">
|
||||
<input class="form-control" :placeholder="messages.rule_expression" v-model="rule.expression">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal" aria-label="Close" @click="resetForm()">##$cancel##</button>
|
||||
<button slot="button" class="btn btn-primary" type="button" v-if="rule.id" v-on:click="saveRule(rule)">##$save_this_rule##</button>
|
||||
<button slot="button" class="btn btn-primary" type="button" v-if="!rule.id" v-on:click="addRule()">##$add_a_rule##</button>
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal" aria-label="Close" @click="resetForm()">{{ messages.cancel }}</button>
|
||||
<button slot="button" class="btn btn-primary" type="button" v-if="rule.id" v-on:click="saveRule(rule)">{{ messages.save_this_rule }}</button>
|
||||
<button slot="button" class="btn btn-primary" type="button" v-if="!rule.id" v-on:click="addRule()">{{ messages.add_a_rule }}</button>
|
||||
</div>
|
||||
</div><!-- /.modal-content -->
|
||||
</div><!-- /.modal-dialog -->
|
|
@ -2,148 +2,21 @@
|
|||
<style>[v-cloak] { display: none; }</style>
|
||||
<div id="rules"></div>
|
||||
|
||||
<script> var existingRules = {{$rules}};</script>
|
||||
<script>
|
||||
var existingRules = {{$rules}};
|
||||
|
||||
var messages = {
|
||||
{{foreach $messages as $key => $value}}
|
||||
{{$key}}: "{{$value}}",
|
||||
{{/foreach}}
|
||||
};
|
||||
|
||||
var csrfToken = "{{$form_security_token}}";
|
||||
|
||||
var currentTheme = "{{$current_theme}}";
|
||||
</script>
|
||||
|
||||
<!-- JS -->
|
||||
<script src="{{$baseurl}}/view/asset/vue/dist/vue.min.js"></script>
|
||||
<script>
|
||||
$.extend({
|
||||
ajaxJSON: function(method, url, data) {
|
||||
return $.ajax({
|
||||
type: method.toUpperCase(),
|
||||
url: url,
|
||||
data: JSON.stringify(data),
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
dataType: 'json'
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
new Vue({
|
||||
el: '#rules',
|
||||
|
||||
data: {
|
||||
showModal: false,
|
||||
errorMessage: '',
|
||||
editedIndex: null,
|
||||
rule: {id: '', name: '', expression: '', created: ''},
|
||||
rules: existingRules || [],
|
||||
itemUrl: '',
|
||||
itemJson: ''
|
||||
},
|
||||
|
||||
watch: {
|
||||
showModal: function () {
|
||||
if (this.showModal) {
|
||||
$(this.$refs.vuemodal).modal('show');
|
||||
} else {
|
||||
$(this.$refs.vuemodal).modal('hide');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
mounted: function() {
|
||||
$.ajaxSetup({headers: {'X-CSRF-Token': document.querySelector('#csrf').getAttribute('value')}});
|
||||
},
|
||||
|
||||
methods: {
|
||||
resetForm: function() {
|
||||
this.rule = {id: '', name: '', expression: '', created: ''};
|
||||
this.showModal = false;
|
||||
this.editedIndex = null;
|
||||
},
|
||||
|
||||
addRule: function () {
|
||||
if (this.rule.name.trim()) {
|
||||
this.errorMessage = '';
|
||||
|
||||
var self = this;
|
||||
$.ajaxJSON('post', '/advancedcontentfilter/api/rules', this.rule)
|
||||
.then(function (responseJSON) {
|
||||
self.rules.push(responseJSON.rule);
|
||||
self.resetForm();
|
||||
}, function (response) {
|
||||
self.errorMessage = response.responseJSON.message;
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
editRule: function (rule) {
|
||||
this.editedIndex = this.rules.indexOf(rule);
|
||||
this.rule = Object.assign({}, rule);
|
||||
this.showModal = true;
|
||||
},
|
||||
|
||||
saveRule: function (rule) {
|
||||
this.errorMessage = '';
|
||||
|
||||
var self = this;
|
||||
$.ajaxJSON('put', '/advancedcontentfilter/api/rules/' + rule.id, rule)
|
||||
.then(function () {
|
||||
self.rules[self.editedIndex] = rule;
|
||||
self.resetForm();
|
||||
}, function (response) {
|
||||
self.errorMessage = response.responseJSON.message;
|
||||
});
|
||||
},
|
||||
|
||||
toggleActive: function (rule) {
|
||||
var previousValue = this.rules[this.rules.indexOf(rule)].active;
|
||||
var newValue = Math.abs(parseInt(rule.active) - 1);
|
||||
|
||||
this.rules[this.rules.indexOf(rule)].active = newValue;
|
||||
|
||||
var self = this;
|
||||
$.ajaxJSON('put', '/advancedcontentfilter/api/rules/' + rule.id, {'active': newValue})
|
||||
.fail(function (response) {
|
||||
self.rules[self.rules.indexOf(rule)].active = previousValue;
|
||||
console.log(response.responseJSON.message);
|
||||
});
|
||||
},
|
||||
|
||||
deleteRule: function (rule) {
|
||||
if (confirm('Are you sure you want to delete this rule?')) {
|
||||
var self = this;
|
||||
$.ajaxJSON('delete', '/advancedcontentfilter/api/rules/' + rule.id)
|
||||
.then(function () {
|
||||
self.rules.splice(self.rules.indexOf(rule), 1);
|
||||
}, function (response) {
|
||||
console.log(response.responseJSON.message);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
showVariables: function () {
|
||||
var urlParts = this.itemUrl.split('/');
|
||||
var guid = urlParts[urlParts.length - 1];
|
||||
|
||||
this.itemJson = '';
|
||||
|
||||
var self = this;
|
||||
$.ajaxJSON('get', '/advancedcontentfilter/api/variables/' + guid)
|
||||
.then(function (responseJSON) {
|
||||
self.itemJson = responseJSON.variables;
|
||||
}, function (response) {
|
||||
self.itemJson = response.responseJSON.message;
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
// These render function have been compiled from templates/vue_dom.tpl, check this file out for instructions
|
||||
render: function () {
|
||||
with(this){return _c('div',{attrs:{"id":"rules"}},[_m(0),_m(1),_c('div',[_v("{{$advanced_content_filter_intro}}")]),_c('h2',[_v("{{$your_rules}}"),_c('button',{staticClass:"btn btn-primary btn-sm",attrs:{"title":"{{$add_a_rule}}"},on:{"click":function($event){showModal = true}}},[_c('i',{staticClass:"fa fa-plus fa-2x",attrs:{"aria-hidden":"true"}})])]),(rules.length === 0)?_c('div',{},[_v("{{$no_rules}}")]):_e(),_c('ul',{staticClass:"list-group"},_l((rules),function(rule){return _c('li',{staticClass:"list-group-item"},[_c('p',{staticClass:"pull-right"},[(parseInt(rule.active))?_c('button',{staticClass:"btn btn-xs btn-primary",attrs:{"type":"button","aria-label":"{{$disable_this_rule}}","title":"{{$disable_this_rule}}"},on:{"click":function($event){toggleActive(rule)}}},[_c('i',{staticClass:"fa fa-toggle-on",attrs:{"aria-hidden":"true"}}),_v(" {{$enabled}}")]):_c('button',{staticClass:"btn btn-xs btn-default",attrs:{"type":"button","aria-label":"{{$enable_this_rule}}","title":"{{$enable_this_rule}}"},on:{"click":function($event){toggleActive(rule)}}},[_c('i',{staticClass:"fa fa-toggle-off",attrs:{"aria-hidden":"true"}}),_v(" {{$disabled}}")]),_c('button',{staticClass:"btn btn-xs btn-primary",attrs:{"type":"button","aria-label":"{{$edit_this_rule}}","title":"{{$edit_this_rule}}"},on:{"click":function($event){editRule(rule)}}},[_c('i',{staticClass:"fa fa-pencil",attrs:{"aria-hidden":"true"}})]),_c('button',{staticClass:"btn btn-xs btn-default",attrs:{"type":"button","aria-label":"{{$delete_this_rule}}","title":"{{$delete_this_rule}}"},on:{"click":function($event){deleteRule(rule)}}},[_c('i',{staticClass:"fa fa-trash-o",attrs:{"aria-hidden":"true"}})])]),_c('h3',{staticClass:"list-group-item-heading"},[_v("{{$rule}} #"+_s(rule.id)+": "+_s(rule.name))]),(rule.expression)?_c('pre',{staticClass:"list-group-item-text"},[_v(_s(rule.expression))]):_e()])})),_c('div',{ref:"vuemodal",staticClass:"modal fade",attrs:{"tabindex":"-1","role":"dialog"}},[_c('div',{staticClass:"modal-dialog",attrs:{"role":"document"}},[_c('div',{staticClass:"modal-content"},[_c('div',{staticClass:"modal-header"},[_c('button',{staticClass:"close",attrs:{"type":"button","data-dismiss":"modal","aria-label":"{{$close}}"},on:{"click":function($event){showModal = false}}},[_c('span',{attrs:{"aria-hidden":"true"}},[_v("×")])]),(rule.id)?_c('h3',[_v("{{$edit_the_rule}} \""+_s(rule.name)+"\"")]):_e(),(!rule.id)?_c('h3',[_v("{{$add_a_rule}}")]):_e()]),_c('div',{staticClass:"modal-body"},[_c('form',[_c('input',{attrs:{"type":"hidden","name":"form_security_token","id":"csrf","value":"{{$form_security_token}}"}}),(errorMessage)?_c('div',{staticClass:"alert alert-danger",attrs:{"role":"alert"}},[_v(_s(errorMessage))]):_e(),_c('div',{staticClass:"form-group"},[_c('input',{directives:[{name:"model",rawName:"v-model",value:(rule.name),expression:"rule.name"}],staticClass:"form-control",attrs:{"placeholder":"{{$rule_name}}"},domProps:{"value":(rule.name)},on:{"input":function($event){if($event.target.composing)return;$set(rule, "name", $event.target.value)}}})]),_c('div',{staticClass:"form-group"},[_c('input',{directives:[{name:"model",rawName:"v-model",value:(rule.expression),expression:"rule.expression"}],staticClass:"form-control",attrs:{"placeholder":"{{$rule_expression}}"},domProps:{"value":(rule.expression)},on:{"input":function($event){if($event.target.composing)return;$set(rule, "expression", $event.target.value)}}})])])]),_c('div',{staticClass:"modal-footer"},[_c('button',{staticClass:"btn btn-default",attrs:{"type":"button","data-dismiss":"modal","aria-label":"Close"},on:{"click":function($event){resetForm()}}},[_v("{{$cancel}}")]),(rule.id)?_c('button',{staticClass:"btn btn-primary",attrs:{"slot":"button","type":"button"},on:{"click":function($event){saveRule(rule)}},slot:"button"},[_v("{{$save_this_rule}}")]):_e(),(!rule.id)?_c('button',{staticClass:"btn btn-primary",attrs:{"slot":"button","type":"button"},on:{"click":function($event){addRule()}},slot:"button"},[_v("{{$add_a_rule}}")]):_e()])])])]),_c('form',{staticClass:"form-inline",on:{"submit":function($event){$event.preventDefault();showVariables()}}},[_c('fieldset',[_c('legend',[_v("Show post variables")]),_c('div',{staticClass:"form-group",staticStyle:{"width":"50%"}},[_c('label',{staticClass:"sr-only",attrs:{"for":"itemUrl"}},[_v("Post URL or item guid")]),_c('input',{directives:[{name:"model",rawName:"v-model",value:(itemUrl),expression:"itemUrl"}],staticClass:"form-control",staticStyle:{"width":"100%"},attrs:{"id":"itemUrl","placeholder":"Post URL or item guid"},domProps:{"value":(itemUrl)},on:{"input":function($event){if($event.target.composing)return;itemUrl=$event.target.value}}})]),_c('button',{staticClass:"btn btn-primary",attrs:{"type":"submit"}},[_v("Show Variables")])])]),_c('pre',{},[_v(_s(itemJson))])])}
|
||||
},
|
||||
|
||||
staticRenderFns: [
|
||||
function () {
|
||||
with(this){return _c('p',[_c('a',{attrs:{"href":"settings/addon"}},[_v("🔙 {{$backtosettings}}")])])}
|
||||
},
|
||||
function () {
|
||||
with(this){return _c('h1',[_v("{{$title}}"),_c('a',{staticClass:"btn btn-default btn-sm",attrs:{"href":"{{$baseurl}}/advancedcontentfilter/help","title":"{{$help}}"}},[_c('i',{staticClass:"fa fa-question fa-2x",attrs:{"aria-hidden":"true"}})])])}
|
||||
}
|
||||
]
|
||||
});
|
||||
</script>
|
||||
<script src="{{$baseurl}}/addon/advancedcontentfilter/advancedcontentfilter.js"></script>
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue