Create your first plugin
In this series of tutorials, we will create a sport
plugin with custom pages, a custom block for the Codex editor, and a custom field for the Codex model builder.
The sport
plugin contains information about football teams and matches. It works with static dummy data, but you can easily connect it with any API.
The idea of these tutorials is to walk you through the steps needed to take to create a plugin for Codex. Feel free to use the files created through this tutorial for your first plugin in Codex.
The first step is to create the necessary files for our plugin.
Codex works with the Vue.js framework, and all plugins for Codex are created using Vue. Therefore, these tutorials require familiarity with the Vue framework and how it works.
Define the manifest file
This tutorial will define the required plugin metadata in the manifest file. Then in the following tutorials, we will explain the required metadata for creating pages, blocks, or fields.
{
"plugin_name": "sport",
"plugin_display_name": "Sport",
"version": "1.0.0",
}
Define a dummy Sport API
Since in these tutorials, we will create multiple components that need access to data for demonstration purposes, we will create a dummy sports API file for storing some data that will help us along the tutorials. Feel free to change this data by connecting your plugin to Codex API or an external API.
- Create a new directory named
shared
- Create a new file named
sportApi.js
const teams = [
{
name: "Manchester City",
league: 'English Premier League',
nation: 'England',
ranking: 3
},
{
name: "Liverpool",
league: 'English Premier League',
nation: 'England',
ranking: 2
},
{
name: "Chelsea",
league: 'English Premier League',
nation: 'England',
ranking: 5
},
{
name: "PSG",
league: 'Ligue 1',
nation: 'France',
ranking: 7
},
{
name: "Olympique Marseille",
league: 'Ligue 1',
nation: 'France',
ranking: 2
},
{
name: "Bayern Munich",
league: 'Bundesliga',
nation: 'Germany',
ranking: 1
},
{
name: "Borussia Dortmund",
league: 'Bundesliga',
nation: 'Germany',
ranking: 19
},
{
name: "AC Milan",
league: 'Serie A',
nation: 'Italy',
ranking: 45
},
{
name: "Inter Milan",
league: 'Serie A',
nation: 'Italy',
ranking: 23
},
{
name: "Real Madrid",
league: 'La Liga',
nation: 'Italy',
ranking: 4
},
{
name: "Barcelona",
league: 'La Liga',
nation: 'Italy',
ranking: 6
},
{
name: "Atletico Madrid",
league: 'La Liga',
nation: 'Italy',
ranking: 9
},
]
const matches = [
{
firstTeam: teams[0],
firstTeamScore: 1,
secondTeam: teams[1],
secondTeamScore: 2
},
{
firstTeam: teams[2],
firstTeamScore: 3,
secondTeam: teams[3],
secondTeamScore: 1
},
{
firstTeam: teams[4],
firstTeamScore: 2,
secondTeam: teams[5],
secondTeamScore: 3
},
{
firstTeam: teams[6],
firstTeamScore: 1,
secondTeam: teams[7],
secondTeamScore: 5
},
{
firstTeam: teams[8],
firstTeamScore: 1,
secondTeam: teams[9],
secondTeamScore: 1
},
{
firstTeam: teams[10],
firstTeamScore: 0,
secondTeam: teams[11],
secondTeamScore: 0
},
]
export function getTeams() {
return teams;
}
export function getMatches() {
return matches;
}
Define a match Vue component
Let's also define a Vue component that we will reuse across our tutorials while developing our plugin.
The MatchDetails
plugin is a simple Vue component that displays information and the score about a specific match, which accepts as a prop.
Create a new file under the shared
directory and name it MatchDetails.vue
.
<template>
<p v-if="match">
<span>{{ match.firstTeam.name }}</span>
<span>{{ match.firstTeamScore }}</span>
<span>-</span>
<span>{{ match.secondTeamScore }}</span>
<span>{{ match.secondTeam.name }}</span>
</p>
<p v-else>
Missing match info
</p>
</template>
<script>
export default {
props: {
match: {
type: Object,
default: null
}
},
}
</script>
<style scoped>
span {
margin: 10px;
}
</style>
Directory structure
After creating the initial necessary files, your directory structure should be like this
root-directory
│ .codexignore
│ manifest.json
└───shared
│ │ sportApi.js
│ │ MatchDetails.vue
Now you are ready to create your first custom page in Codex through the following tutorial.