-
Notifications
You must be signed in to change notification settings - Fork 0
Content format
Let's consider the following article about the difference quotient as an example:
The content can be separated in a list of logical sub-elements like "text", "equation" or "GeoGebra applet" in the above example. More elements like "multiple choice exercise", "video" or "definition" can be considered. We call these logical elements of a content "plugins". A plugin is described in JSON in the form:
{
"plugin": "...", // name of the plugin
"state": ... // necessary information to describe the plugin
}
Each plugin defines the form of its state. For example, for rendering an externally hosted GeoGebra applet we only need its ID on geogebra.org
and thus
only a string
. In the above example we have
the GeoGebra applet with ID nnrmthf4
and thus we describe the
applet integration via the JSON:
{
"plugin": "geogebra",
"state": "nnrmthf4"
}
In this form we can describe the whole content and thereby get a list of plugins. We unite this list in a so
called rows
plugin. The rows
plugin describes semantically an arbitrary list of plugins from a list of possible
plugin types. So we end up with the following JSON:
This content format can be used to describe arbitrary educational content. When a new content format is needed (like a certain type of interactive exercise) we can define a plugin type. In this way the content format of Serlo is easily extendable.
Plugins can be also used to structure content. An example is our article
plugin for serlo.org. We learned that a
good article at our website follows a certain structure: There is often a short introduction in the beginning, possibly
with a picture illustrating the topic. Afterwards, there is the main content which is followed by exercises and links to
related content. Since we wanted to help our authors to create high quality content, we introduced the article
plugin a couple of months ago. It follows the basic structure we identified to be useful (in the editing mode all
elements besides the main content are optional):
You can use template plugins to standardize your own content formats or learning scenarios and guide your authors accordingly.
We can combine the power of template plugins with the list of available content plugins. In the following you see content format for the article "Differenzenquotient":
Metadata about a plugin - like the license
and the description meta_description
of an article - is also stored
inside the state
object:
{
"plugin": "article",
"state": {
"id": 234583,
"license": {
"id": 1,
"title": "Dieses Werk steht unter der freien Lizenz CC BY-SA 4.0.",
"url": "https://creativecommons.org/licenses/by-sa/4.0/deed.de",
"iconHref": "https://i.creativecommons.org/l/by-sa/4.0/88x31.png"
},
"title": "Differenzenquotient",
"meta_title": "Differenzenquotient",
"meta_description": "Der Differenzenquotient beschreibt..."
}
}
The following plugins are already implemented (see also this list in our source code).
-
anchor
– an anchor which can be referenced in a link
interface Anchor {
plugin: "anchor",
// Name of the anchor
//
// The anchor will be rendered as <div id="{plugin.state}"/>,
// so that it can be referenced as http://serlo.org/xyz#{plugin.state}
// in links
state: string
}
-
box
– a semantic box like an example, a definition, a theorem, a hint, etc.
interface Box {
plugin: "box",
// The box will be rendered as <figure id="{plugin.state.anchorId}">
state: {
// type of box: blank, example, citation, approach, .
type: string,
// optional title for the box
title: {
plugin: "text",
state: {}
},
// name of anchor so that the box can be referenced in links (see anchor)
anchorId: string,
// a box can contain text, code, equations, image, multimedia content or a table
// any of the above is wrapped in a rows plugin
content: {
plugin: "rows",
state: {}
}
}
}
- [deprecated]
blockquote
– a citation
interface Blockquote {
plugin: "blockquote",
// The blockquote is rendered as <blockquote/> and contains a text plugin
state: {
content: {
plugin: "text",
state: {}
}
}
}
equations
interface Equations {
plugin: "equations",
// The equations are rendered as <table/>
state: {
// The transformations are saved as steps where each step contains a left-hand side, a sign, a right-hand side, the transformation and a textual explanation (inline)
steps: [
{
left: string,
sign: string,
right: string,
transform: string,
explanation: {
plugin: "text",
state: {}
}
],
// The first explanation is rendered above the equation sign of the first step
firstExplanation: {
plugin: "text",
state: {}
}
transformationTarget: 'equation',
}
}
-
image
– an image
interface Image {
plugin: "image",
// An image is rendered as <img src="{plugin.state.src}" alt="{plugin.state.alt?}">
state: {
// The url to the image's location
src: string,
// The image can be a link
link?: {
// The url of the link
href: string,
// Option to open the link in a new tab
openInNewTab: false
},
// alternative information for an image if image cannot be viewed
alt?: string,
// Optional setting of the maximal width of the image
maxWidth?: number,
// Optional caption that can be added to the image
caption?: {
plugin: 'text',
state: {}
}
}
}
-
multimedia
– text with an illustration media object (like an image)
interface Multimedia {
plugin: "multimedia",
state: {
// The left-hand side of the multimedia object can contain text, a highlight, an anchor, equations, an image or a serloTable
explanation: {
plugin: "rows",
state: {}
},
// The right-hand side can be either an image, a video or a geogebra applet
multimedia: {
plugin: "image",
state: {}
},
illustrating: true,
width: number
},
}
-
rows
– an arbitrary list of plugins from a defined list of plugin types
interface Rows {
plugin: "rows",
// The rows plugin is rendered as a div with an tab index
// The rows are a list of plugins from a predefined plugin registry
state: [
{
plugin: "text",
state: {}
}
]
}
-
separator
– a separator (e.g.<hr/>
in HTML)
interface Separator {
plugin: "separator",
state: undefined
}
-
spoiler
– a spoiler
interface Spoiler {
plugin: "spoiler",
// The spoiler is a drop down that can be opened inside an article
state: {
// title of the spoiler
title: string,
// A spoiler contains rows of text or other content types
content: {
plugin: "rows",
state: {}
}
}
}
-
serloTable
- a table with row and column headers
interface SerloTable {
plugin: "serloTable",
// The Serlo Table is structured into rows where each row contains a column list. Each row-column entry is a text content.
state: {
rows: [
{
columns: [
{
content: {
plugin: "text",
state: {}
}
}
]
}
],
// Specifies whether only column headers or only row headers or both are displayed
tableType: string
}
}
-
text
– a rich text element
interface Text {
plugin: "text",
state: SlateValue
}
-
video
– an included video
interface Video {
state: {
src: string,
alt: string
}
}
-
geogebra
– an included GeoGebra applet
interface Geogebra {
state: string
}
-
inputExercise
– an exercise with an input element
interface InputExercise {
state: {
type: string,
unit: string,
answers: [
{
value: string,
isCorrect: boolean,
feedback: {
plugin: Text
}
}
]
}
}
-
scMcExercise
– single or multiple choice exercise
interface ScMcExercise {
isSingleChoice: false,
answers: [
{
content: {
plugin: Text
},
isCorrect: false,
feedback: {
plugin: Text
}
}
]
}
-
serloInjection
– another content of serlo.org which shall be included
interface SerloInjection {
plugin: "injection",
// Id of the Serlo article that is injected
state: string
}
-
solution
– the solution of an exercise
interface Solution {
prerequisite?: {
id: string,
title: string,
},
strategy: {
plugin: Text
},
steps: {
plugin: Rows
}
}
-
textExercise
– an exercise
-
serloArticle
– a basic structure of an article for serlo.org -
serloArticleIntroduction
– the introduction of an article
interface SerloArticleIntroduction {
plugin: "articleIntroduction",
// The articleIntroduction is a special type of the multimedia plugin where the explanation is a text plugin and the multimedia content type is restricted to images
state: {
// The text on the left-hand side of the image
explanation: {
plugin: "text",
state: {}
}
// The image to the right-hand side of the text
multimedia: {
plugin: "image",
state: {}
}
}
}
-
important
– a box with an important message
interface Important {
plugin: "important",
// important is a rendered as a special box and contains the message as a text plugin
state: {
plugin: "text",
state: {}
}
}
-
table
– a table
interface Table {
plugin: "table",
// the markdown string
state: string
}
- "Fill the blanks" exercises
- "Drag and Drop" exercises
- "Image hotspot" exercises
- Home
- Serlo Infrastructure
- Serlo Infrastructure for Non programmers
- Resources for new programmers
- Setup of the toolchain
- Best Practices
- Data Privacy for Devs
- How Tos
- Single Sign On
- Integration with the Data Wallet
- User Journey
- Integration of "Datenraum" into the Serlo Editor
- Introduction to the Serlo editor
- Core concepts of the Serlo editor
- Packages of the Serlo editor
- Creating a new plugin (outdated)
- Redux process in the Serlo editor
- The content format of the Serlo editor
- Serlo Editor Plugin Initial State
- How the Serlo Editor is integrated into edu-sharing via LTI
- Learner Events and xAPI