Skip to content

4. JSON Rendering

Yousef Z edited this page May 1, 2023 · 14 revisions

This is the alternative way to use πŸƒ Qalib.You use the keys to the embed as the

You can then have multiple embeds which are each contained in a JSON object, and it's key needs to uniquely identifies them among the other embed keys, and is written as {"test_key": { ... }, "test_key2": { ... }}

To render values dynamically, simply put them in between braces, and the renderer will format it when you use the context's rendered_send() method, as seen in the next section.

It is safe to skip any non-mandatory fields that an embed would not require, they will simply use their default values.

🧩 Sample

{
  "test_key": {
    "embed": {
      "title": "Test",
      "description": "Test Description",
      "type": "rich",
      "colour": "55,55,55",
      "timestamp": {
        "date": "{todays_date}"
      },
      "url": "https://www.discord.com",
      "fields": [
        {
          "name": "Test Field",
          "text": "Test Text"
        }
      ],
      "footer": {
        "text": "Test Footer",
        "icon": "https://cdn.discordapp.com/embed/avatars/0.png"
      },
      "thumbnail": "https://cdn.discordapp.com/embed/avatars/0.png",
      "image": "https://cdn.discordapp.com/embed/avatars/0.png",
      "author": {
        "name": "{author_name}",
        "icon": "https://cdn.discordapp.com/embed/avatars/0.png",
        "url": "https://discordapp.com"
      }
    }
  },
  "test_key2": {
    "embed": {
      "title": "Test",
      "colour": "magenta",
      "fields": [
        {
          "name": "Test Field",
          "text": "Test Text"
        }
      ]
    }
  }
}

For the purpose of this example, we store this file in templates/test.json

⚑ Using QalibContext

from typing import Literal

import discord
from discord.ext import commands

import qalib
from qalib.template_engines.formatter import Formatter


Messages = Literal["test_key", "test_key2"]
bot = commands.AutoShardedBot(command_prefix="!", intents=discord.Intents.all())

@bot.command()
@qalib.qalib_context(Formatter(), "templates/test.json")
async def test(ctx: qalib.QalibContext[Messages], name: str):
    await ctx.rendered_send("test_key", keywords={
        "author_name": str
    })

πŸ–ŒοΈ Views

The main components are rendered and instantiate the mapped component/item in discord.py. The limit to the number of components/items that you can use in one embed is capped at 25.

For each example we will write how the component should look like. Components/Items should be written in the view section, where the comment is.

{
  "test_key2": {
    "embed": {
      "title": "Test2",
      "description": "Test Description",
      "colour": "magenta",
      "fields": [
        {
          "name": "Test Field",
          "text": "Test Text"
        }
      ]
    },
    "view": {
      "components": []
    }
  }
}

πŸ†— Button

Rendering a Button in .json.

"button_key": {
  "type": "button",
  "label": "Click Me!",
  "style": "success",
  "custom_id": "{custom_id}",
  "disabled": true,
  "url": "https://github.com/YousefEZ/discord-qalib",
  "emoji": {
    "name": "joy"
  }
}

🏴 Select

Rendering a Select in .json

"select_key": {
  "placeholder": "Select An Option",
  "custom_id": "{custom_id}",
  "min_values": 1,
  "max_values": 3,
  "disabled": false
  "options": [
    {
      "label": "Amman"
      "value": 0,
      "description": "The capital city of Jordan",
      "emoji": {
        "name": "Petra",
        "id": 217348923789,
        "animated": false
      }
    },
    {
      "label": "Baghdad"
    },
    {
      "label": "Cairo"
    },
    {
      "label": "Damascus"
    }
  ]
}

πŸ“£ Channel Select

Rendering a Channel Select in .json

"channel_key": {
  "type": "channel_select",
  "placeholder": "Select A Channel",
  "channel_types": ["text", "private"],
  "min_values": 1,
  "max_values": 2,
  "disabled": false,
}

🏷️ Mentionable Select

Rendering a Mentionable Select in .json

"mentionable_key": {
  "type": "mentionable_select",
  "placeholder": "Select Something to Mention",
  "min_values": 1,
  "max_values": 2,
  "disabled": false,
}

πŸ₯· User Select

Rendering a User Select in .json

"user_key": {
  "type": "user_select",
  "placeholder": "Select A User",
  "min_values": 1,
  "max_values": 2,
  "disabled": false,
}

🎭 Role Select

Rendering a Role Select in .json

"role_key": {
  "type": "role_select",
  "placeholder": "Select A Role",
  "min_values": 1,
  "max_values": 2,
  "disabled": false,
}

πŸ’¬ Text Input

Rendering a Text Input in .json

"text_select": {
  "label": "What do you think?",
  "style": "short",
  "placeholder": "Write your response...",
  "default": "N/A",
  "min_length": 0,
  "max_length": 150
}

πŸ“ Modal

Modals can be rendered, simply by using the key to Modal as the key to JSON object. They also need to be passed the methods using their method names as their keys. A Sample document containing Modals can be seen here

{
  "modal1": {
    "title": "Modal 1",
    "components": {
      "name": {
        "type": "text_input",
        "label": "What is your name?",
        "placeholder": "Enter your name"
      },
      "age": {
        "type": "text_input",
        "label": "What is your age?",
        "placeholder": "Enter your age"
      }
    }
  }
}

πŸ“– Menus

Menus can be rendered by using the <menu> tag with a key identifier such as <menu key="test">, following messages or page references <page key="other_test"> that refer to messages outside of the menu tag

{
  "test1": {
    "type": "message",
    "content" This is a test"
  },
  "Menu1": {
    "type": "menu",
    "pages": [
      "test1",
      {
        "type": "message",
        "content": "This is the second page"
      }
}

πŸ’₯ Expansive

these are messages that expand to another message if the main embed's field overrun the character limit, forming a menu. This is compatible with menus.

{
  "test1": {
    "timeout": null,
    "type": "expansive",
    "embed": {
      "title": "Hello World",
      "color": "magenta",
      "expansive_field": {
        "name": "hello world",
        "inline": "true",
        "value": "ultrices neque ornare aenean euismod elementum nisi quis eleifend quam adipiscing vitae proin sagittis nisl rhoncus mattis rhoncus urna neque viverra justo nec ultrices dui sapien eget mi proin sed libero enim sed faucibus turpis in eu mi bibendum neque egestas congue quisque egestas diam in arcu cursus euismod quis viverra nibh cras pulvinar mattis nunc sed blandit libero volutpat sed cras ornare arcu dui vivamus arcu felis bibendum ut tristique et egestas quis ipsum suspendisse ultrices gravida dictum fusce ut placerat orci nulla pellentesque dignissim enim sit amet venenatis urna cursus eget nunc scelerisque viverra mauris in aliquam sem ultrices neque ornare aenean euismod elementum nisi quis eleifend quam adipiscing vitae proin sagittis nisl rhoncus mattis rhoncus urna neque viverra justo nec ultrices dui sapien eget mi proin sed libero enim sed faucibus turpis in eu mi bibendum neque egestas congue quisque egestas diam in arcu cursus euismod quis viverra nibh cras pulvinar mattis nunc sed blandit libero volutpat sed cras ornare arcu dui vivamus arcu felis bibendum ut tristique et egestas quis ipsum suspendisse ultrices gravida dictum fusce ut placerat orci nulla pellentesque dignissim enim sit amet venenatis urna cursus eget nunc scelerisque viverra mauris in aliquam sem"
      }
    }
  }
}

This will expand into two messages and form a menu