Merge branch 'develop' of https://github.com/tainacan/tainacan into develop

This commit is contained in:
weryques 2018-09-04 15:22:40 -03:00
commit e5a0dd7ae1
27 changed files with 655 additions and 150 deletions

View File

@ -2,15 +2,16 @@
Notes for a future documentation
Tainacan uses the ordinary WordPress template hierarchy for its templates. It adds only 3 additional templates in your hierarchy
Tainacan uses the ordinary WordPress template hierarchy for its templates. It adds additional templates in the hierarchy
* `tainacan/single-items.php` - Used in the single template for any item of any collection
* `tainacan/arhive-items.php` - Used in the list of items of any collection
* `tainacan/arhive-items.php` - Used in the list of items of any collection (e.g. both archive-tnc_col_4_item.php and archive-tnc_col_5_item.php)
* `tainacan/archive-taxonomy.php` - Used as a template for all Tainacan Taxonomies (list items based on a term)
* `tainacan/archive-repository.php` - Used in the `/items/` URL, which is added by the Tainacan plugin, and lists all items of all collections
Since each collection is a new custom post type, these templates are usefull to create a template that will be used by all collections.
Nevertheless, you are still able to create more specific templates, using the standar WordPress hierarchy.
Nevertheless, you are still able to create more specific templates, using the standard WordPress hierarchy.
Examples:

View File

@ -0,0 +1,9 @@
<?php
/**
* @see \Tainacan\Admin_Hooks->register()
*/
function register_admin_hook( $context, $callback, $position = 'end-left' ) {
$admin_hooks = \Tainacan\Admin_Hooks::get_instance();
return $admin_hooks->register( $context, $callback, $position );
}

View File

@ -0,0 +1,66 @@
<?php
namespace Tainacan;
class Admin_Hooks {
private $registered_hooks = [];
private static $instance = null;
public static function get_instance() {
if ( ! isset( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
add_action('init', [$this, 'init']);
}
function init() {
do_action('tainacan-register-admin-hooks');
}
public function get_available_positions() {
return apply_filters('tainacan-admin-hooks-positions', ['begin-left', 'begin-right', 'end-left', 'end-right']);
}
public function get_available_contexts() {
return apply_filters('tainacan-admin-hooks-contexts', ['collection', 'metadatum', 'item', 'taxonomy', 'term', 'filter']);
}
public function get_registered_hooks() {
return $this->registered_hooks;
}
/**
*
* @param string $context The context to add the hook to (collection, metadatum, item, taxonomy, term or filter)
* @param string $position The position inside the page to hook. (begin, end, begin-left, begin-right, end-left, end-right)
* @param callable $callback The callback that will output the form HTML
*/
public function register( $context, $callback, $position = 'end-left' ) {
$contexts = $this->get_available_contexts();
$positions = $this->get_available_positions();
if ( !in_array($context, $contexts) || !in_array($position, $positions) ) {
return false;
}
$result = call_user_func($callback);
if (is_string($result)){
$this->registered_hooks[$context][$position][] = $result;
return true;
}
return false;
}
}

View File

@ -203,7 +203,9 @@ class Admin {
foreach ( $metadata_types as $index => $metadata_type){
$class = new $metadata_type;
$settings['i18n']['helpers_label'][$class->get_component()] = $class->get_form_labels();
}
}
$settings['form_hooks'] = Admin_Hooks::get_instance()->get_registered_hooks();
return $settings;

View File

@ -27,6 +27,15 @@
@blur="updateSlug"
@focus="clearErrors('name')"/>
</b-field>
<!-- Hook for extra Form options -->
<template
v-if="formHooks != undefined &&
formHooks['collection'] != undefined &&
formHooks['collection']['begin-left'] != undefined">
<form
id="form-collection-begin-left"
v-html="this.formHooks['collection']['begin-left'].join('')"/>
</template>
<!-- Thumbnail -------------------------------- -->
<b-field :addons="false">
@ -221,6 +230,18 @@
:title="$i18n.getHelperTitle('collections', 'allow_comments')"
:message="$i18n.getHelperMessage('collections', 'allow_comments')"/>
</b-field>
<!-- Hook for extra Form options -->
<template
v-if="formHooks != undefined &&
formHooks['collection'] != undefined &&
formHooks['collection']['end-left'] != undefined">
<form
ref="form-collection-end-left"
id="form-collection-end-left"
v-html="formHooks['collection']['end-left'].join('')"/>
</template>
</div>
<div class="column is-1" />
<div class="column">
@ -284,7 +305,17 @@
</div>
</div>
</b-field>
<!-- Hook for extra Form options -->
<template
v-if="formHooks != undefined &&
formHooks['collection'] != undefined &&
formHooks['collection']['begin-right'] != undefined">
<form
id="form-collection-begin-right"
v-html="formHooks['collection']['begin-right'].join('')"/>
</template>
<!-- Description -------------------------------- -->
<b-field
:addons="false"
@ -385,7 +416,18 @@
v-model="form.slug"
@focus="clearErrors('slug')"/>
</b-field>
<!-- Hook for extra Form options -->
<template
v-if="formHooks != undefined &&
formHooks['collection'] != undefined &&
formHooks['collection']['end-right'] != undefined">
<form
id="form-collection-end-right"
v-html="formHooks['collection']['end-right'].join('')"/>
</template>
</div>
</div>
<!-- Form submit -------------------------------- -->
@ -418,11 +460,11 @@ import { mapActions } from 'vuex';
import wpMediaFrames from '../../js/wp-media-frames';
import FileItem from '../other/file-item.vue';
import EyeIcon from '../other/eye-icon.vue';
import { wpAjax } from '../../js/mixins';
import { wpAjax, formHooks } from '../../js/mixins';
export default {
name: 'CollectionEditionForm',
mixins: [ wpAjax ],
mixins: [ wpAjax, formHooks ],
data(){
return {
collectionId: Number,
@ -481,7 +523,7 @@ export default {
viewModesList: [],
fromImporter: '',
newPagePath: tainacan_plugin.admin_url + 'post-new.php?post_type=page',
isUpdatingSlug: false,
isUpdatingSlug: false
}
},
components: {
@ -526,8 +568,8 @@ export default {
});
}, 500),
onSubmit() {
this.isLoading = true;
this.form.moderators_ids = [];
for (let moderator of this.moderators)
this.form.moderators_ids.push(moderator.id);
@ -546,10 +588,16 @@ export default {
default_view_mode: this.form.default_view_mode,
allow_comments: this.form.allow_comments
};
this.updateCollection(data).then(updatedCollection => {
this.fillExtraFormData(data, 'collection');
this.updateCollection({collection_id: this.collectionId, collection: data })
.then(updatedCollection => {
this.collection = updatedCollection;
// Fills hook forms with it's real values
this.updateExtraFormData('collection', this.collection);
// Fill this.form data with current data.
this.form.name = this.collection.name;
this.form.slug = this.collection.slug;
@ -586,6 +634,8 @@ export default {
// Creates draft Collection
let data = { name: '', description: '', status: 'auto-draft', mapper: (this.isMapped && this.mapper != false ? this.mapper : false ) };
this.fillExtraFormData(data, 'collection');
this.sendCollection(data).then(res => {
this.collectionId = res.id;
@ -593,7 +643,7 @@ export default {
// Initializes Media Frames now that collectonId exists
this.initializeMediaFrames();
// Fill this.form data with current data.
this.form.name = this.collection.name;
this.form.description = this.collection.description;
@ -758,7 +808,7 @@ export default {
}
}
},
created(){
mounted(){
if (this.$route.query.fromImporter != undefined)
this.fromImporter = this.$route.query.fromImporter;
@ -779,7 +829,13 @@ export default {
// Initializes Media Frames now that collectonId exists
this.initializeMediaFrames();
this.$nextTick()
.then(() => {
// Fills hook forms with it's real values
this.updateExtraFormData('collection', this.collection);
});
// Fill this.form data with current data.
this.form.name = this.collection.name;
this.form.description = this.collection.description;

View File

@ -2,7 +2,8 @@
<form
id="filterEditForm"
class="tainacan-form"
@submit.prevent="saveEdition(editForm)">
@submit.prevent="saveEdition(editForm)">
<b-field
:addons="false"
:type="formErrors['name'] != undefined ? 'is-danger' : ''"
@ -22,6 +23,16 @@
@focus="clearErrors('name')"/>
</b-field>
<!-- Hook for extra Form options -->
<template
v-if="formHooks != undefined &&
formHooks['filter'] != undefined &&
formHooks['filter']['begin-left'] != undefined">
<form
id="form-filter-begin-left"
v-html="formHooks['filter']['begin-left'].join('')"/>
</template>
<b-field
:addons="false"
:type="formErrors['description'] != undefined ? 'is-danger' : ''"
@ -135,6 +146,16 @@
<div
v-html="editForm.edit_form"
v-else/>
<!-- Hook for extra Form options -->
<template
v-if="formHooks != undefined &&
formHooks['filter'] != undefined &&
formHooks['filter']['end-left'] != undefined">
<form
id="form-filter-end-left"
v-html="formHooks['filter']['end-left'].join('')"/>
</template>
<div class="field is-grouped form-submit">
<div class="control">
@ -156,9 +177,11 @@
<script>
import { mapActions } from 'vuex';
import { formHooks } from "../../js/mixins";
export default {
name: 'FilterEditionForm',
mixins: [ formHooks ],
data(){
return {
editForm: {},
@ -182,6 +205,13 @@ export default {
this.oldForm = JSON.parse(JSON.stringify(this.originalFilter));
},
mounted() {
// Fills hook forms with it's real values
this.$nextTick()
.then(() => {
this.updateExtraFormData('filter', this.editForm);
});
},
beforeDestroy() {
if (this.closedByForm) {
this.editedFilter.saved = true;
@ -201,6 +231,7 @@ export default {
if ((filter.filter_type_object && filter.filter_type_object.form_component) || filter.edit_form == '') {
// this.fillExtraFormData(this.editForm, 'filter');
this.updateFilter({ filterId: filter.id, index: this.index, options: this.editForm})
.then(() => {
this.editForm = {};
@ -229,6 +260,7 @@ export default {
formObj[key] = value;
}
this.fillExtraFormData(formObj, 'filter');
this.updateFilter({ filterId: filter.id, index: this.index, options: formObj})
.then(() => {
this.editForm = {};
@ -265,7 +297,7 @@ export default {
@import "../../scss/_variables.scss";
form {
form#filterEditForm {
padding: 1.0em 2.0em;
border-top: 1px solid $gray2;
border-bottom: 1px solid $gray2;

View File

@ -16,6 +16,16 @@
<div class="columns">
<div class="column is-5-5">
<!-- Hook for extra Form options -->
<template
v-if="formHooks != undefined &&
formHooks['item'] != undefined &&
formHooks['item']['begin-left'] != undefined">
<form
id="form-item-begin-left"
v-html="formHooks['item']['begin-left'].join('')"/>
</template>
<!-- Document -------------------------------- -->
<div class="section-label">
<label>{{ form.document != undefined && form.document != null && form.document != '' ? $i18n.get('label_document') : $i18n.get('label_document_empty') }}</label>
@ -292,11 +302,31 @@
</div>
</div>
<!-- Hook for extra Form options -->
<template
v-if="formHooks != undefined &&
formHooks['item'] != undefined &&
formHooks['item']['end-left'] != undefined">
<form
id="form-item-end-left"
v-html="formHooks['item']['end-left'].join('')"/>
</template>
</div>
<div
class="column is-4-5"
v-show="!isMetadataColumnCompressed">
<!-- Hook for extra Form options -->
<template
v-if="formHooks != undefined &&
formHooks['item'] != undefined &&
formHooks['item']['begin-right'] != undefined">
<form
id="form-item-begin-right"
v-html="formHooks['item']['begin-right'].join('')"/>
</template>
<!-- Visibility (status public or private) -------------------------------- -->
<div class="section-label">
@ -341,16 +371,14 @@
<!-- Metadata from Collection-------------------------------- -->
<span class="section-label">
<label >{{ $i18n.get('metadata') }}</label>
<label>{{ $i18n.get('metadata') }}</label>
</span>
<br>
<a
class="collapse-all"
@click="toggleCollapseAll()">
{{ collapseAll ? $i18n.get('label_collapse_all') : $i18n.get('label_expand_all') }}
<b-icon
type="is-turoquoise5"
:icon=" collapseAll ? 'menu-down' : 'menu-right'" />
<b-icon :icon=" collapseAll ? 'menu-down' : 'menu-right'" />
</a>
<tainacan-form-item
v-for="(metadatum, index) of metadatumList"
@ -359,6 +387,15 @@
:is-collapsed="metadatumCollapses[index]"
@changeCollapse="onChangeCollapse($event, index)"/>
<!-- Hook for extra Form options -->
<template
v-if="formHooks != undefined &&
formHooks['item'] != undefined &&
formHooks['item']['end-right'] != undefined">
<form
id="form-item-end-right"
v-html="formHooks['item']['end-right'].join('')"/>
</template>
</div>
</div>
<div class="footer">
@ -443,9 +480,11 @@ import wpMediaFrames from '../../js/wp-media-frames';
import FileItem from '../other/file-item.vue';
import DocumentItem from '../other/document-item.vue';
import CustomDialog from '../other/custom-dialog.vue';
import { formHooks } from '../../js/mixins';
export default {
name: 'ItemEditionForm',
mixins: [ formHooks ],
data(){
return {
pageTitle: '',
@ -540,12 +579,15 @@ export default {
let previousStatus = this.form.status;
this.form.status = status;
let data = {item_id: this.itemId, status: this.form.status, comment_status: this.form.comment_status};
let data = {id: this.itemId, status: this.form.status, comment_status: this.form.comment_status};
this.fillExtraFormData(data, 'item');
this.updateItem(data).then(updatedItem => {
this.item = updatedItem;
// Fills hook forms with it's real values
this.updateExtraFormData('item', this.item);
// Fill this.form data with current data.
this.form.status = this.item.status;
this.form.document = this.item.document;
@ -582,6 +624,7 @@ export default {
// Creates draft Item
let data = {collection_id: this.form.collectionId, status: 'auto-draft', comment_status: this.form.comment_status};
this.fillExtraFormData(data, 'item');
this.sendItem(data).then(res => {
this.itemId = res.id;
@ -806,6 +849,12 @@ export default {
this.fetchItem(this.itemId).then(res => {
this.item = res;
// Fills hook forms with it's real values
this.$nextTick()
.then(() => {
this.updateExtraFormData('item', this.item);
});
// Fill this.form data with current data.
this.form.status = this.item.status;
this.form.document = this.item.document;
@ -907,6 +956,10 @@ export default {
.page-container {
padding: 25px 0px;
&>.tainacan-form {
margin-bottom: 110px;
}
.tainacan-page-title {
padding-left: $page-side-padding;
padding-right: $page-side-padding;
@ -945,7 +998,7 @@ export default {
label {
font-size: 16px !important;
font-weight: 500 !important;
color: $blue5 !important;
color: $gray5 !important;
line-height: 1.2em;
}
}

View File

@ -24,6 +24,16 @@
@focus="clearErrors('name')"/>
</b-field>
<!-- Hook for extra Form options -->
<template
v-if="formHooks != undefined &&
formHooks['metadatum'] != undefined &&
formHooks['metadatum']['begin-left'] != undefined">
<form
id="form-metadatum-begin-left"
v-html="formHooks['metadatum']['begin-left'].join('')"/>
</template>
<b-field
:addons="false"
:type="formErrors['description'] != undefined ? 'is-danger' : ''"
@ -206,6 +216,16 @@
v-html="editForm.edit_form"
v-else/>
<!-- Hook for extra Form options -->
<template
v-if="formHooks != undefined &&
formHooks['metadatum'] != undefined &&
formHooks['metadatum']['end-left'] != undefined">
<form
id="form-metadatum-end-left"
v-html="formHooks['metadatum']['end-left'].join('')"/>
</template>
<div class="field is-grouped form-submit">
<div class="control">
<button
@ -228,9 +248,11 @@
<script>
import {mapActions} from 'vuex';
import { formHooks } from "../../js/mixins";
export default {
name: 'MetadatumEditionForm',
mixins: [ formHooks ],
data() {
return {
editForm: {},
@ -257,6 +279,13 @@
this.oldForm = JSON.parse(JSON.stringify(this.originalMetadatum));
},
mounted() {
// Fills hook forms with it's real values
this.$nextTick()
.then(() => {
this.updateExtraFormData('metadatum', this.editForm);
});
},
beforeDestroy() {
if (this.closedByForm) {
this.editedMetadatum.saved = true;
@ -275,7 +304,8 @@
saveEdition(metadatum) {
if ((metadatum.metadata_type_object && metadatum.metadata_type_object.form_component) || metadatum.edit_form == '') {
this.fillExtraFormData(this.editForm, 'metadatum');
this.updateMetadatum({
collectionId: this.collectionId,
metadatumId: metadatum.id,
@ -309,6 +339,7 @@
for (let [key, value] of formData.entries())
formObj[key] = value;
this.fillExtraFormData(formObj, 'metadatum');
this.updateMetadatum({
collectionId: this.collectionId,
metadatumId: metadatum.id,

View File

@ -25,6 +25,16 @@
@blur="updateSlug()"/>
</b-field>
<!-- Hook for extra Form options -->
<template
v-if="formHooks != undefined &&
formHooks['taxonomy'] != undefined &&
formHooks['taxonomy']['begin-left'] != undefined">
<form
id="form-taxonomy-begin-left"
v-html="formHooks['taxonomy']['begin-left'].join('')"/>
</template>
<!-- Description -------------------------------- -->
<b-field
:addons="false"
@ -99,6 +109,16 @@
</div>
</b-field>
<!-- Hook for extra Form options -->
<template
v-if="formHooks != undefined &&
formHooks['taxonomy'] != undefined &&
formHooks['taxonomy']['end-left'] != undefined">
<form
id="form-taxonomy-end-left"
v-html="formHooks['taxonomy']['end-left'].join('')"/>
</template>
<!-- Submit -->
<div class="field is-grouped form-submit">
<div class="control">
@ -133,14 +153,14 @@
</template>
<script>
import { wpAjax } from "../../js/mixins";
import { wpAjax, formHooks } from "../../js/mixins";
import { mapActions, mapGetters } from 'vuex';
import TermsList from '../lists/terms-list.vue';
import CustomDialog from '../other/custom-dialog.vue';
export default {
name: 'TaxonomyEditionForm',
mixins: [ wpAjax ],
mixins: [ wpAjax, formHooks ],
data(){
return {
taxonomyId: String,
@ -169,8 +189,7 @@
label: this.$i18n.get('trash')
}],
editFormErrors: {},
formErrorMessage: '',
// baseUrl: tainacan_plugin.base_url,
formErrorMessage: ''
}
},
components: {
@ -225,16 +244,19 @@
taxonomyId: this.taxonomyId,
name: this.form.name,
description: this.form.description,
slug: this.form.slug,
slug: this.form.slug ? this.form.slug : '',
status: this.form.status,
allowInsert: this.form.allowInsert
allow_insert: this.form.allowInsert
};
this.fillExtraFormData(data, 'taxonomy');
this.updateTaxonomy(data)
.then(updatedTaxonomy => {
this.taxonomy = updatedTaxonomy;
// Fills hook forms with it's real values
this.updateExtraFormData('taxonomy', this.taxonomy);
// Fill this.form data with current data.
this.form.name = this.taxonomy.name;
this.form.slug = this.taxonomy.slug;
@ -291,9 +313,9 @@
description: '',
status: 'auto-draft',
slug: '',
allowInsert: '',
allow_insert: '',
};
this.fillExtraFormData(data, 'taxonomy');
this.createTaxonomy(data)
.then(res => {
@ -324,8 +346,8 @@
return ( this.form.allowInsert === 'yes' ) ? this.$i18n.get('label_yes') : this.$i18n.get('label_no');
}
},
created(){
mounted(){
if (this.$route.fullPath.split("/").pop() === "new") {
this.createNewTaxonomy();
} else if (this.$route.fullPath.split("/").pop() === "edit" || this.$route.fullPath.split("/").pop() === "terms") {
@ -339,6 +361,12 @@
this.fetchTaxonomy(this.taxonomyId).then(res => {
this.taxonomy = res.taxonomy;
// Fills hook forms with it's real values
this.$nextTick()
.then(() => {
this.updateExtraFormData('taxonomy', this.taxonomy);
});
// Fill this.form data with current data.
this.form.name = this.taxonomy.name;
this.form.description = this.taxonomy.description;

View File

@ -63,6 +63,16 @@
@focus="clearErrors({ name: 'name', repeated: 'repeated' })"/>
</b-field>
<!-- Hook for extra Form options -->
<template
v-if="formHooks != undefined &&
formHooks['term'] != undefined &&
formHooks['term']['begin-left'] != undefined">
<form
id="form-term-begin-left"
v-html="formHooks['term']['begin-left'].join('')"/>
</template>
<!-- Description -------------- -->
<b-field
:addons="false"
@ -122,6 +132,16 @@
</transition>
</b-field>
<!-- Hook for extra Form options -->
<template
v-if="formHooks != undefined &&
formHooks['term'] != undefined &&
formHooks['term']['end-left'] != undefined">
<form
id="form-term-end-left"
v-html="formHooks['term']['end-left'].join('')"/>
</template>
<!-- Submit buttons -------------- -->
<div class="field is-grouped form-submit">
<div class="control">
@ -154,11 +174,13 @@
</template>
<script>
import { formHooks } from "../../js/mixins";
import {mapActions, mapGetters} from 'vuex';
import wpMediaFrames from '../../js/wp-media-frames';
export default {
name: 'TermEditionForm',
mixins: [ formHooks ],
data() {
return {
formErrors: {},
@ -190,12 +212,16 @@
saveEdition(term) {
if (term.id === 'new') {
this.sendChildTerm({
taxonomyId: this.taxonomyId,
let data = {
name: this.editForm.name,
description: this.editForm.description,
parent: this.hasParent ? this.editForm.parent : 0,
headerImageId: this.editForm.header_image_id,
header_image_id: this.editForm.header_image_id,
};
this.fillExtraFormData(data, 'term');
this.sendChildTerm({
taxonomyId: this.taxonomyId,
term: data
})
.then((term) => {
this.$emit('onEditionFinished', {term: term, hasChangedParent: this.hasChangedParent });
@ -213,13 +239,17 @@
} else {
this.updateChildTerm({
taxonomyId: this.taxonomyId,
termId: this.editForm.id,
let data = {
term_id: this.editForm.id,
name: this.editForm.name,
description: this.editForm.description,
parent: this.hasParent ? this.editForm.parent : 0,
headerImageId: this.editForm.header_image_id,
header_image_id: this.editForm.header_image_id,
}
this.fillExtraFormData(data, 'term');
this.updateChildTerm({
taxonomyId: this.taxonomyId,
term: data
})
.then((term) => {
this.formErrors = {};
@ -312,6 +342,12 @@
},
mounted() {
// Fills hook forms with it's real values
this.$nextTick()
.then(() => {
this.updateExtraFormData('term', this.editForm);
});
this.showCheckboxesWarning = false;
this.hasParent = this.editForm.parent != undefined && this.editForm.parent > 0;
this.initialParentId = this.editForm.parent;
@ -358,7 +394,7 @@
}
}
form {
form#termEditForm {
padding: 1.7rem 0 1.5rem 1.5rem;
border-left: 1px solid $gray2;
margin-left: 0.75rem;

View File

@ -583,12 +583,6 @@ export default {
}
}
form {
padding: 1.0em 2.0em;
border-top: 1px solid $gray2;
border-bottom: 1px solid $gray2;
margin-top: 1.0em;
}
&.not-sortable-item, &.not-sortable-item:hover {
cursor: default;
background-color: white !important;

View File

@ -46,4 +46,80 @@ export const dateInter = {
return format.replace(/[\w]/g, '#');
}
}
};
// Used for filling extra form data on hooks
export const formHooks = {
data() {
return {
formHooks: JSON.parse(JSON.stringify(tainacan_plugin['form_hooks']))
}
},
methods: {
fillExtraFormData(data, entity) {
let positions = [
'begin-left',
'begin-right',
'end-left',
'end-right'
];
// Gets data from existing extra form hooks
for (let position of positions) {
if (this.formHooks[entity][position] && this.formHooks[entity][position] != undefined) {
let formElement = document.getElementById('form-' + entity + '-' + position);
if (formElement) {
for (let element of formElement.elements) {
if (element.type == "checkbox" || (element.type == "select" && element.multiple != undefined && element.multiple == true)) {
if (element.checked && element.name != undefined && element.name != '') {
if (!Array.isArray(data[element.name]))
data[element.name] = [];
data[element.name].push(element.value);
}
} else if (element.type == "radio") {
if (element.checked && element.name != undefined && element.name != '')
data[element.name] = element.value;
} else {
data[element.name] = element.value;
}
}
}
}
}
},
updateExtraFormData(entity, entityObject) {
let positions = [
'begin-left',
'begin-right',
'end-left',
'end-right'
];
// Gets data from existing extra form hooks
for (let position of positions) {
if (this.formHooks[entity][position] && this.formHooks[entity][position] != undefined) {
let formElement = document.getElementById('form-' + entity + '-' + position);
if (formElement) {
for (let element of formElement.elements) {
for (let key of Object.keys(entityObject)) {
if (element['name'] == key) {
if (Array.isArray(entityObject[key])) {
let obj = entityObject[key].find((value) => { return value == element['value'] });
element['checked'] = obj != undefined ? true : false;
} else {
if (entityObject[key] != null && entityObject[key] != undefined && entityObject[key] != ''){
if (element.type == "radio")
element['checked'] = entityObject[key] == element['value'] ? true : false;
else
element['value'] = entityObject[key];
}
}
}
}
}
}
}
}
}
}
};

View File

@ -13,6 +13,16 @@
<div class="columns">
<div class="column is-5-5">
<!-- Hook for extra Form options -->
<template
v-if="formHooks != undefined &&
formHooks['view-item'] != undefined &&
formHooks['view-item']['begin-left'] != undefined">
<div
id="view-item-begin-left"
v-html="formHooks['view-item']['begin-left'].join('')"/>
</template>
<!-- Document -------------------------------- -->
<div class="section-label">
<label>{{ item.document !== undefined && item.document !== null && item.document !== '' ?
@ -156,11 +166,32 @@
</b-collapse>
</div>
</div>
<!-- Hook for extra Form options -->
<template
v-if="formHooks != undefined &&
formHooks['view-item'] != undefined &&
formHooks['view-item']['end-left'] != undefined">
<div
id="view-item-end-left"
v-html="formHooks['view-item']['end-left'].join('')"/>
</template>
</div>
<div
v-show="!isMetadataColumnCompressed"
class="column is-4-5">
<!-- Hook for extra Form options -->
<template
v-if="formHooks != undefined &&
formHooks['view-item'] != undefined &&
formHooks['view-item']['begin-right'] != undefined">
<div
id="view-item-begin-right"
v-html="formHooks['view-item']['begin-right'].join('')"/>
</template>
<!-- Visibility (status public or private) -------------------------------- -->
<div class="section-label">
<label>{{ $i18n.get('label_visibility') }}</label>
@ -235,6 +266,16 @@
</b-collapse>
</div>
</div>
<!-- Hook for extra Form options -->
<template
v-if="formHooks != undefined &&
formHooks['view-item'] != undefined &&
formHooks['view-item']['end-right'] != undefined">
<div
id="view-item-end-right"
v-html="formHooks['view-item']['end-right'].join('')"/>
</template>
</div>
</div>
<div class="footer">
@ -260,9 +301,11 @@
import {mapActions, mapGetters} from 'vuex'
import FileItem from '../../components/other/file-item.vue';
import DocumentItem from '../../components/other/document-item.vue';
import { formHooks } from '../../js/mixins';
export default {
name: 'ItemPage',
mixins: [ formHooks ],
data() {
return {
collectionId: Number,
@ -329,6 +372,9 @@
},
computed: {
item() {
// Fills hook forms with it's real values
this.updateExtraFormData('item', this.getItem());
return this.getItem();
},
metadatumList() {
@ -411,6 +457,10 @@
.page-container {
padding: 25px 0;
&>.tainacan-form {
margin-bottom: 110px;
}
.tainacan-page-title {
padding-left: $page-side-padding;
padding-right: $page-side-padding;
@ -472,7 +522,7 @@
label {
font-size: 16px !important;
font-weight: 500 !important;
color: $blue5 !important;
color: $gray5 !important;
line-height: 1.2em;
}
}

View File

@ -203,7 +203,20 @@ class REST_Collections_Controller extends REST_Controller {
$item_arr['total_items']['private'] = $total_items->private;
}
return $item_arr;
/**
* Use this filter to add additional post_meta to the api response
* Use the $request object to get the context of the request and other variables
* For example, id context is edit, you may want to add your meta or not.
*
* Also take care to do any permissions verification before exposing the data
*/
$extra_metadata = apply_filters('tainacan-api-response-collection-meta', [], $request);
foreach ($extra_metadata as $extra_meta) {
$item_arr[$extra_meta] = get_post_meta($item_arr['id'], $extra_meta, true);
}
return $item_arr;
}
return $item;

View File

@ -331,6 +331,19 @@ class REST_Filters_Controller extends REST_Controller {
$item_arr['filter_type_object'] = $item->get_filter_type_object() ? $item->get_filter_type_object()->_toArray() : $item->get_filter_type_object();
/**
* Use this filter to add additional post_meta to the api response
* Use the $request object to get the context of the request and other variables
* For example, id context is edit, you may want to add your meta or not.
*
* Also take care to do any permissions verification before exposing the data
*/
$extra_metadata = apply_filters('tainacan-api-response-filter-meta', [], $request);
foreach ($extra_metadata as $extra_meta) {
$item_arr[$extra_meta] = get_post_meta($item_arr['id'], $extra_meta, true);
}
return $item_arr;
}

View File

@ -183,6 +183,19 @@ class REST_Items_Controller extends REST_Controller {
$item_arr['url'] = get_permalink( $item_arr['id'] );
$item_arr['exposer_urls'] = \Tainacan\Exposers\Exposers::get_exposer_urls(get_rest_url(null, "{$this->namespace}/{$this->rest_base}/{$item->get_id()}/"));
/**
* Use this filter to add additional post_meta to the api response
* Use the $request object to get the context of the request and other variables
* For example, id context is edit, you may want to add your meta or not.
*
* Also take care to do any permissions verification before exposing the data
*/
$extra_metadata = apply_filters('tainacan-api-response-item-meta', [], $request);
foreach ($extra_metadata as $extra_meta) {
$item_arr[$extra_meta] = get_post_meta($item_arr['id'], $extra_meta, true);
}
return $item_arr;
}

View File

@ -321,6 +321,19 @@ class REST_Metadata_Controller extends REST_Controller {
$item_arr['enabled'] = $item->get_enabled_for_collection();
}
/**
* Use this filter to add additional post_meta to the api response
* Use the $request object to get the context of the request and other variables
* For example, id context is edit, you may want to add your meta or not.
*
* Also take care to do any permissions verification before exposing the data
*/
$extra_metadata = apply_filters('tainacan-api-response-metadatum-meta', [], $request);
foreach ($extra_metadata as $extra_meta) {
$item_arr[$extra_meta] = get_post_meta($item_arr['id'], $extra_meta, true);
}
return $item_arr;
}

View File

@ -106,6 +106,19 @@ class REST_Taxonomies_Controller extends REST_Controller {
$item_arr = $this->filter_object_by_attributes($item, $attributes_to_filter);
}
/**
* Use this filter to add additional post_meta to the api response
* Use the $request object to get the context of the request and other variables
* For example, id context is edit, you may want to add your meta or not.
*
* Also take care to do any permissions verification before exposing the data
*/
$extra_metadata = apply_filters('tainacan-api-response-taxonomy-meta', [], $request);
foreach ($extra_metadata as $extra_meta) {
$item_arr[$extra_meta] = get_post_meta($item_arr['id'], $extra_meta, true);
}
return $item_arr;
}

View File

@ -277,6 +277,19 @@ class REST_Terms_Controller extends REST_Controller {
$item_arr = $this->filter_object_by_attributes($item, $attributes_to_filter);
}
/**
* Use this filter to add additional term_meta to the api response
* Use the $request object to get the context of the request and other variables
* For example, id context is edit, you may want to add your meta or not.
*
* Also take care to do any permissions verification before exposing the data
*/
$extra_metadata = apply_filters('tainacan-api-response-term-meta', [], $request);
foreach ($extra_metadata as $extra_meta) {
$item_arr[$extra_meta] = get_term_meta($item_arr['id'], $extra_meta, true);
}
return $item_arr;
}

View File

@ -131,6 +131,10 @@ $Tainacan_Embed = \Tainacan\Embed::get_instance();
require_once(__DIR__ . '/../admin/class-tainacan-admin.php');
$Tainacan_Admin = \Tainacan\Admin::get_instance();
require_once(__DIR__ . '/../admin/class-tainacan-admin-hooks.php');
require_once(__DIR__ . '/../admin/admin-hooks-functions.php');
$Tainacan_Admin_Hooks = \Tainacan\Admin_Hooks::get_instance();
require_once(__DIR__ . '/../theme-helper/class-tainacan-theme-helper.php');
require_once(__DIR__ . '/../theme-helper/template-tags.php');
$Tainacan_Theme_Helper = \Tainacan\Theme_Helper::get_instance();

View File

@ -3,7 +3,7 @@ import axios from '../../../axios/axios';
// Actions related to background processes
export const fetchProcesses = ({ commit }, {page, processesPerPage}) => {
return new Promise((resolve, reject) => {
let endpoint = '/bg-processes?';
let endpoint = '/bg-processes?all_users=1';
if (page != undefined)
endpoint += 'paged=' + page;

View File

@ -227,49 +227,11 @@ export const deleteCollection = ({ commit }, { collectionId, isPermanently }) =>
export const updateCollection = ({ commit }, {
collection_id,
name,
description,
slug,
status,
enable_cover_page,
cover_page_id,
moderators_ids,
parent,
enabled_view_modes,
default_view_mode,
comment_status,
allow_comments
collection
}) => {
return new Promise((resolve, reject) => {
axios.tainacan.patch('/collections/' + collection_id, {
name: name,
description: description,
status: status,
slug: slug,
cover_page_id: "" + cover_page_id,
enable_cover_page: enable_cover_page,
moderators_ids: moderators_ids,
parent: parent,
enabled_view_modes: enabled_view_modes,
default_view_mode: default_view_mode,
comment_status: comment_status,
allow_comments: allow_comments
}).then( res => {
commit('setCollection', {
id: collection_id,
name: name,
description: description,
slug: slug,
status: status,
enable_cover_page: enable_cover_page,
cover_page_id: cover_page_id,
moderators_ids: moderators_ids,
parent: parent,
enabled_view_modes: enabled_view_modes,
default_view_mode: default_view_mode,
comment_status: comment_status,
allow_comments: allow_comments
});
axios.tainacan.patch('/collections/' + collection_id, collection).then( res => {
commit('setCollection', collection);
commit('setCollectionName', res.data.name);
commit('setCollectionURL', res.data.url);
resolve( res.data );
@ -280,18 +242,16 @@ export const updateCollection = ({ commit }, {
});
};
export const sendCollection = ( { commit }, { name, description, status, mapper }) => {
export const sendCollection = ( { commit }, collection) => {
return new Promise(( resolve, reject ) => {
var param = {
name: name,
description: description,
status: status,
};
param[tainacan_plugin.exposer_mapper_param] = mapper;
var param = collection;
param['mapper'] = null;
param[tainacan_plugin.exposer_mapper_param] = collection.mapper;
axios.tainacan.post('/collections/', param)
.then( res => {
commit('setCollection', { name: name, description: description, status: status, mapper: mapper });
resolve( res.data );
let collection = res.data;
commit('setCollection', collection);
resolve( collection );
})
.catch(error => {
reject( error.response );

View File

@ -92,12 +92,9 @@ export const fetchItemTitle = ({ commit }, id) => {
});
}
export const sendItem = ( { commit }, { collection_id, status, comment_status }) => {
export const sendItem = ( { commit }, item) => {
return new Promise(( resolve, reject ) => {
axios.tainacan.post('/collection/'+ collection_id + '/items/', {
status: status,
comment_status: comment_status
})
axios.tainacan.post('/collection/'+ item.collection_id + '/items/', item)
.then( res => {
commit('setItem', res.data);
commit('setLastUpdated');
@ -109,13 +106,10 @@ export const sendItem = ( { commit }, { collection_id, status, comment_status })
});
};
export const updateItem = ({ commit }, { item_id, status, comment_status }) => {
export const updateItem = ({ commit }, item) => {
return new Promise((resolve, reject) => {
axios.tainacan.patch('/items/' + item_id, {
status: status,
comment_status: comment_status
}).then( res => {
axios.tainacan.patch('/items/' + item.id, item).then( res => {
commit('setItem', res.data);
commit('setLastUpdated');
resolve( res.data );

View File

@ -4,13 +4,7 @@ import qs from 'qs'
// TAXONOMIES
export const createTaxonomy = ({commit}, taxonomy) => {
return new Promise(( resolve, reject ) => {
axios.tainacan.post('/taxonomies', {
name: taxonomy.name,
description: taxonomy.description,
status: taxonomy.status,
slug: taxonomy.slug,
allow_insert: taxonomy.allowInsert
})
axios.tainacan.post('/taxonomies', taxonomy)
.then( res => {
let taxonomy = res.data;
commit('setTaxonomy', taxonomy);
@ -39,18 +33,10 @@ export const deleteTaxonomy = ({ commit }, { taxonomyId, isPermanently }) => {
export const updateTaxonomy = ({ commit }, taxonomy) => {
return new Promise(( resolve, reject ) => {
axios.tainacan.patch(`/taxonomies/${taxonomy.taxonomyId}`, {
name: taxonomy.name,
description: taxonomy.description,
status: taxonomy.status,
slug: taxonomy.slug ? taxonomy.slug : '',
allow_insert: taxonomy.allowInsert
})
axios.tainacan.patch(`/taxonomies/${taxonomy.taxonomyId}`, taxonomy)
.then( res => {
let taxonomy = res.data;
commit('setTaxonomy', taxonomy);
resolve( taxonomy );
})
.catch(error => {
@ -239,18 +225,13 @@ export const fetchChildTerms = ({ commit }, { parentId, taxonomyId, fetchOnly, s
});
};
export const sendChildTerm = ({ commit }, { taxonomyId, name, description, parent, headerImageId }) => {
export const sendChildTerm = ({ commit }, { taxonomyId, term }) => {
return new Promise(( resolve, reject ) => {
axios.tainacan.post(`/taxonomy/${taxonomyId}/terms/`, {
name: name,
description: description,
parent: parent,
header_image_id: headerImageId,
})
axios.tainacan.post(`/taxonomy/${taxonomyId}/terms/`, term)
.then( res => {
let term = res.data;
commit('addChildTerm', {term: term, parent: parent });
resolve( term );
let newTerm = res.data;
commit('addChildTerm', {term: newTerm, parent: term.parent });
resolve( newTerm );
})
.catch(error => {
reject({ error_message: error['response']['data'].error_message, errors: error['response']['data'].errors });
@ -258,17 +239,12 @@ export const sendChildTerm = ({ commit }, { taxonomyId, name, description, paren
});
};
export const updateChildTerm = ({ commit }, { taxonomyId, termId, name, description, parent, headerImageId, oldParent }) => {
export const updateChildTerm = ({ commit }, { taxonomyId, term }) => {
return new Promise(( resolve, reject ) => {
axios.tainacan.patch(`/taxonomy/${taxonomyId}/terms/${termId}`, {
name: name,
description: description,
parent: parent,
header_image_id: headerImageId,
})
axios.tainacan.patch(`/taxonomy/${taxonomyId}/terms/${term.term_id}`, term)
.then( res => {
let term = res.data;
commit('updateChildTerm', { term: term, parent: parent, oldParent: oldParent });
let updatedTerm = res.data;
commit('updateChildTerm', { term: updatedTerm, parent: updatedTerm.parent, oldParent: term.parent });
resolve( term );
})
.catch(error => {

View File

@ -279,6 +279,11 @@ class Migrations {
flush_rewrite_rules(false);
}
static function refresh_rewrite_rules_items() {
// needed after we added the /items rewrite rule
flush_rewrite_rules(false);
}
}

View File

@ -49,6 +49,13 @@ class Theme_Helper {
add_filter('get_the_archive_title', array($this, 'filter_archive_title'));
add_shortcode( 'tainacan-search', array($this, 'search_shortcode'));
add_action( 'generate_rewrite_rules', array( &$this, 'rewrite_rules' ), 10, 1 );
add_filter( 'query_vars', array( &$this, 'rewrite_rules_query_vars' ) );
add_filter( 'template_include', array( &$this, 'rewrite_rule_template_include' ) );
add_action( 'pre_get_posts', array($this, 'archive_repository_pre_get_posts'));
// TODO: fix the WP Title
// add_filter( 'wp_title', array($this, 'archive_repository_wp_title'), 10, 3);
$this->register_view_mode('table', [
'label' => __('Table', 'tainacan'),
@ -112,7 +119,12 @@ class Theme_Helper {
if (in_array($current_post_type, $collections_post_types)) {
$title = sprintf( __( 'Collection: %s' ), post_type_archive_title( '', false ) );
}
} elseif (is_archive()) {
if (get_query_var('tainacan_repository_archive') == 1) {
$title = __( 'All items in repository', 'tainacan' );
}
}
return $title;
}
@ -323,6 +335,50 @@ class Theme_Helper {
return "<div id='tainacan-items-page' $params ></div>";
}
function rewrite_rules( &$wp_rewrite ) {
/* Translators: The Items slug - will be the URL for the repository archive */
$items_base = sanitize_title(_x('items', 'Slug: the string that will be used to build the URL to list all items of the repository', 'tainacan'));
$new_rules = array(
$items_base . "/?$" => "index.php?tainacan_repository_archive=1",
$items_base . "/page/([0-9]+)/?$" => 'index.php?tainacan_repository_archive=1&paged=$matches[1]'
);
$wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
}
function rewrite_rules_query_vars( $public_query_vars ) {
$public_query_vars[] = "tainacan_repository_archive";
return $public_query_vars;
}
function rewrite_rule_template_include( $template ) {
global $wp_query;
if ( $wp_query->get( 'tainacan_repository_archive' ) == 1 ) {
$templates = apply_filters('tainacan_repository_archive_template_hierarchy', ['tainacan/archive-repository.php', 'index.php']);
return locate_template($templates, false);
}
return $template;
}
function archive_repository_pre_get_posts($wp_query) {
if (!$wp_query->is_main_query() || $wp_query->get( 'tainacan_repository_archive' ) != 1)
return;
$wp_query->set( 'is_archive', true );
$wp_query->set( 'is_post_type_archive', false );
$wp_query->set( 'is_home', false );
$wp_query->is_home = false;
$wp_query->is_post_type_archive = false;
$wp_query->is_archive = true;
$wp_query->set( 'post_type', \Tainacan\Repositories\Repository::get_collections_db_identifiers() );
}
/**

View File

@ -1,3 +1,4 @@
<?php
use \Tainacan\Entities;
@ -181,7 +182,6 @@ function tainacan_the_collection_description() {
function tainacan_the_faceted_search() {
$props = ' ';
$id = '';
// if in a collection page
$collection_id = tainacan_get_collection_id();
@ -190,7 +190,6 @@ function tainacan_the_faceted_search() {
$collection = new \Tainacan\Entities\Collection($collection_id);
$props .= 'default-view-mode="' . $collection->get_default_view_mode() . '" ';
$props .= 'enabled-view-modes="' . implode(',', $collection->get_enabled_view_modes()) . '" ';
$id = 'tainacan-items-page';
}
// if in a tainacan taxonomy
@ -198,10 +197,9 @@ function tainacan_the_faceted_search() {
if ($term) {
$props .= 'term-id="' . $term->term_id . '" ';
$props .= 'taxonomy="' . $term->taxonomy . '" ';
$id = 'tainacan-items-page';
}
echo "<div id='$id' $props ></div>";
echo "<div id='tainacan-items-page' $props ></div>";
}