Here we are going explore how to add a completely custom card to the overview in UiPress. Please note you will need at least version 2.1.4 of UiPress and a basic understanding of php and javascript and Vue.js.

We will add a card that displays a simple message and lets you customise the name and message of the card. The below code can be downloaded in a plugin file here. All the code is very simple and notarised but we explain it all below.

To start with, we are going to explore the php wordpress filter used to load up our custom vue.js component:

add_filter('uipress_register_card', 'register_custom_card');

The above filter receives a list of all UiPress cards and then you can add a custom one and return the new list.

In order to register our card, we will push a simple object to the card array like so in the uip-custom-card.php file.


///Hook into UiPress custom card filter
add_filter('uipress_register_card', 'register_custom_card');


//Add new card to the array of overview cards
function register_custom_card($cards){

///MAKE SURE WE ARE DEALING WITH AN ARRAY
if(!is_array($cards)){
$cards = array();
}

///BUILD CUSTOM CARD OPTIONS
$temp = array();
// Card name
$temp['name'] = __('Hello World','admin2020');
// Module name for vue - must be unique
$temp['moduleName'] = 'hello-world';
// Description of what the card does
$temp['description'] = __('Displays a hello world message.','admin2020');
// Card category - can be anything you like, shows in card selection list
$temp['category'] = __('Custom','admin2020');
//Path to the vue.js component
$temp['componentPath'] = plugin_dir_url( __FILE__ ) . 'hello-world.js';

//PUSH CUSTOM CARD TO CARDS ARRAY
$cards[] = $temp;

//RETURN CARDS ARRAY TO UIPRESS
return $cards;

}

Now we have told UiPress about our new card and where to find it, we now need to look at the vue.js component. Open up the hello-world.js file and you will see the below code:

export function moduleName() {
return "hello-world";
}

export function moduleData() {
return {
props: {
cardData: Object,
overviewData: Object,
},
data: function () {
return {
cardOptions: this.cardData,
loading: true,
};
},
mounted: function () {
this.loading = false;
},
watch: {
cardOptions: {
handler(newValue, oldValue) {
this.$emit("card-change", newValue);
},
deep: true,
},
},
computed: {
returnMessage() {
if (!this.cardOptions.message) {
return "Hello World";
} else {
return this.cardOptions.message;
}
},
},
methods: {},
template:
'<div class="uip-padding-s">\
<loading-placeholder v-if="loading == true"></loading-placeholder>\
<div v-if="!overviewData.ui.editingMode">\
<div class="uip-text-emphasis">{{returnMessage}}</div>\
</div>\
<form v-if="overviewData.ui.editingMode" class="uk-form-stacked">\
<div class="uip-margin-bottom-s uip-flex uip-flex-column">\
<label class="uip-text-bold uip-margin-bottom-xxs" for="form-stacked-text">Card Title</label>\
<input class="uip-input" type="text" v-model="cardOptions.name" placeholder="Card Title">\
</div>\
<div class="uip-flex uip-flex-column">\
<label class="uip-text-bold uip-margin-bottom-xxs">Card Message</label>\
<input class="uip-input" type="text" v-model="cardOptions.message" placeholder="Custom Message">\
</div>\
</form>\
</div>',
};
return compData;
}

This is the component that is responsible for what the card does on the overview page, lets take a look at each section.

Props

props: { cardData: Object, overviewData: Object},

These are passed to every card by UiPress and are very useful when creating custom cards.

The cardData contains all the data about that specific card in the layout like name, width, background colour, any custom values etc. Anything you add to this object will be saved and retrieved every time the overview page is accessed.

The overviewData Object contains the current overview date range, dynamic data required for other cards as well as whether we are in editing mode etc.

We don't use dynamic data in this example, but we do use edittingMode, which is in the overviewData object (overviewData.ui.editingMode). This will equal true when the user puts the overview page in edit mode allowing us to show the form to edit the card data.

The Template

The template provided is just a simple example of what we can do but let’s breakdown each section:

<loading-placeholder v-if="loading == true"></loading-placeholder>\


This is a pre-made component in UiPress, it is responsible for creating the loading placeholders while the cards are fetching data. Because the card we are working on here doesn’t fetch any data from a dynamic source, you don’t really need them but it is useful when data collection can take some time.

<div v-if="!overviewData.ui.editingMode">\
<div class="uip-text-emphasis">{{returnMessage}}</div>\
</div>\

Notice the ‘v-if=”!overviewData.ui.editingMode”‘ in the above, this is so we only show this part of the template when we are not in editing mode

<form v-if="overviewData.ui.editingMode" class="uk-form-stacked">\
<div class="uip-margin-bottom-s uip-flex uip-flex-column">\
<label class="uip-text-bold uip-margin-bottom-xxs"
for="form-stacked-text">
Card Title
</label>\
<input class="uip-input" type="text"
v-model="cardOptions.name" placeholder="Card Title">\
</div>\
<div class="uip-flex uip-flex-column">\
<label class="uip-text-bold uip-margin-bottom-xxs">
Card Message
</label>\
<input class="uip-input" type="text"
v-model="cardOptions.message" placeholder="Custom Message">\
</div>\
</form>\

This part is what will show when we are in editing mode and allows you to edit the card name and message.

The above is just a simple example of what can be done with the overview cards and as always we are always on hand to answer any questions.

Did this answer your question?