Last updated Oct 12, 2021

Rate this page:

Providing context

This is a continuation of the work done in 2. Rendering extensions.

In this section you will learn more on:

  • What context is
  • How to define a schema for your context
  • How to share a context object with extensions

You'll continue working on the tutorial page: http://localhost:7990/bitbucket/plugins/servlet/extension-points

Context

In CSE, context allows you to share information with extensions like the state of the page where the extension is rendered, or a user's session. The context is a contract between your extension point and the extension developers, and as such, it needs to be well documented and typed.

Before you share any context with extension, you first need to define a ContextSchema that will validate that the information you're sharing is correct, and also generates the documentation for you.

Defining a schema for your context

The schema for your context needs to be declared in the same file where you declared your Schema, and it uses the same graphql-style syntax.

On /src/main/my-app/extensions/extension-points-tutorial/schema.cse.graphql, write:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
"""
---
extensionPoint: extension.points.tutorial
---
"""
type Schema {
    # your attributes...
}

type ContextSchema {
    user: String

    luckyNumber: Number
}

ContextSchema is a graphql type that defines the keys and values of the context you are going to share with extensions. In this case, your context will share an object with a user and luckyNumber attribute.

Sharing context with extensions

Once the ContextSchema is defined, all the helpers imported from the schema using CSE schema loader will be aware of it, and will expect this context object to be passed as an argument with the right properties.

On ./src/main/my-app/extensions/extension-points-tutorial/extension-points-page.jsx:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import React, {useState} from 'react

import { useExtensions } from './schema.cse.graphql';

const MyPage = () => {
    const [userInfo, setUserInfo] = useState({user: "Jon Doe", luckyNumber: 42});
    const extensions = useExtensions(userInfo);

    const renderExtension = extension => { /* rendering extension logic */};

    return (
        <PageContainer>
            <h2>extension.points.tutorial</h2>
            {extensions.map(renderExtension)}
        </PageContainer>
    );
};

/** page declaration for guides only **/

Reload the page and now you should see that the panel extension renders the context received on the screen.

If you attempt to pass a context object that doesn't satisfy the ContextSchema, or don't pass any context at all, the CSE runtime will throw an error and point you to where the error is happening. Try it!

Context change

Most of the time, the context you provided will be something that changes depending on what the user does with the product. Thanks to the use of hooks, every time the context changes, it triggers a recalculation of the extension's attributes, validates them and returns them so that you can re-render them.

Take for example a change of the luckyNumber of the user every 10 seconds.

On ./src/main/my-app/extensions/extension-points-tutorial/extension-points-page.jsx:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import React, { useState } from 'react';

import { useExtensions } from './schema.cse.graphql';

const MyPage = () => {
    const [userInfo, setUserInfo] = useState({ user: 'Jon Doe', luckyNumber: 42 });
    const extensions = useExtensions(userInfo);

    useEffect(() => {
        const interval = setInterval(() => {
            setUserInfo({
                ...userInfo,

                luckyNumber: Math.floor(Math.random() * 42),
            });

            return () => clearInterval(interval);
        }, 10000);
    }, []);

    const renderExtension = (extension) => {
        /* rendering extension logic */
    };

    return (
        <PageContainer>
            <h2>extension.points.tutorial</h2>
            {extensions.map(renderExtension)}
        </PageContainer>
    );
};

/** page declaration for guides only **/

If you reload the page, you should see the panel extension rendering the new context every 10 seconds with a new lucky number.

Recap and next steps

So far, you've learned:

  • How to share information with extensions
  • How to define a schema to validate your context
  • How the extension's attributes are recalculated when context changes.

Next, you're going to learn how to use your schema to provide extension point documentation.

Rate this page: