Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

Back to skills

Iblai Api Studio Html

BSecurity

Add and edit HTML (text) components in an Open edX unit on Studio — create the html block, write its HTML body and title in one update, reference uploaded images and files via /static/ paths, duplicate or delete it, and follow the authoring rules that make content look designed (cards, callouts, tables, tooltips via inline CSS) while leaving typography and page width to the LMS. Use when the user wants text, a reading, an explanation, a callout, a comparison table, an embedded video/iframe, o...

15 stars
0 votes
0 copies
0 views
Added 9/20/2026
developmentpythongobashnodeapi

Works with

api

Security Analysis

B88/100
criticalDownloads and executes remote scripts — classic supply chain attack

Scanned 9/20/2026

Install to Claude Code

$npx -y skills add iblai/vibe --skill iblai-api-studio-html --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Iblai Api Studio Html?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Iblai Api Studio Html
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/iblai-iblai-api-studio-html/badge)](https://www.skillsdirectory.com/skills/iblai-iblai-api-studio-html)

More formats (shields.io, HTML) on the badges page.

Download Zip
Files
SKILL.md
---
name: iblai-api-studio-html
description: Add and edit HTML (text) components in an Open edX unit on Studio — create the html block, write its HTML body and title in one update, reference uploaded images and files via /static/ paths, duplicate or delete it, and follow the authoring rules that make content look designed (cards, callouts, tables, tooltips via inline CSS) while leaving typography and page width to the LMS. Use when the user wants text, a reading, an explanation, a callout, a comparison table, an embedded video/iframe, or any rich content inside a unit. Session auth via studio.env; run the auth preflight first.
metadata:
  kind: api
---

# iblai-api-studio-html

The `html` component is the workhorse of course content: any HTML the user
should read. Create it, then write `data` (the HTML) and `metadata.display_name`
(the title). Two calls per component; no editor round-trips.

## Before you start

1. Preflight: `node .claude/skills/iblai-api-studio-auth/scripts/studio-login.mjs --check` prints two `ok`s; otherwise run **`/iblai-api-studio-auth`** first — do not attempt the calls below.
2. A unit locator (`…+type@vertical+block@…`) from `/iblai-api-studio-unit` or `/iblai-api-studio-outline`.
3. If images or files are referenced, upload them first (`POST /assets/{course}/`, `/iblai-api-studio-settings`) and use their `/static/…` paths.

## Auth & conventions

- **Base URL:** `$STUDIO_URL`; Studio session cookies from `studio.env` (its values are single-quoted — bash strips the quotes; any other parser must strip them too, or Studio answers 500: `/iblai-api-studio-auth`).
- **Snippet:**
  ```bash
  set -a; . ./studio.env; set +a
  S=(-s -b "studio_session_id=$STUDIO_SESSION; csrftoken=$STUDIO_CSRF" -H "X-CSRFToken: $STUDIO_CSRF" \
     -H "Origin: $STUDIO_URL" -H "Referer: $STUDIO_URL/" -H "Accept: application/json" -H "Content-Type: application/json")
  ```
- **Keys:** parent = a unit locator; the block is `…+type@html+block@<hex>`.
- Content is a draft until the unit is published (`/iblai-api-studio-publish`). DELETE is destructive — confirm with the user first.
- A `500` HTML page on these calls = malformed session cookie (`/iblai-api-studio-auth`, "Reading failures"), not bad HTML — Studio stores any string.

## Reads

- **GET** `/xblock/{html}` — `{ "id", "display_name", "category": "html", "data": "<html string>", "metadata": { "display_name" }, "published", "has_changes", … }`.
- **GET** `/api/v1/ibl/xblock/get-details?locator=<url-encoded html locator>` — `{ "id", "data", "display_name" }` (lighter; `406` for non-html blocks).
- **GET** `/api/contentstore/v1/container/vertical/{unit}/children` — the unit's components in order (`block_type: "html"`, `name`, `block_id`).

## Writes

- **POST** `/xblock/` — create an empty text block (appends to the unit):
  ```json
  { "parent_locator": "<unit>", "category": "html" }
  ```
  → `{ "locator": "…+type@html+block@<hex>", "courseKey": "…" }`.
  Optional `"boilerplate": "announcement.yaml"` pre-fills an announcement template; `"display_name"` is ignored on create — set it in the update.
- **POST** `/xblock/{html}` — write the content (this is the whole edit):
  ```json
  { "data": "<section>…</section>", "metadata": { "display_name": "Why data matters" } }
  ```
  → `{ "id", "data": "<the stored HTML>", "metadata": { "display_name": "…" } }`. `data` replaces the previous body entirely; `metadata` is merged.
  (Equivalent v1 route: `POST /api/v1/ibl/xblock/update` `{ "locator", "category": "html", "courseKey", "data", "metadata": { "display_name" } }` → `200`; `/iblai-api-studio-outline`.)
- **POST** `/xblock/` `{ "duplicate_source_locator": "<html>", "parent_locator": "<unit>" }` — copy into the same or another unit.
- **DELETE** `/xblock/{html}` → `204`. Confirm with the user first.

## Example

```bash
set -a; . ./studio.env; set +a
S=(-s -b "studio_session_id=$STUDIO_SESSION; csrftoken=$STUDIO_CSRF" -H "X-CSRFToken: $STUDIO_CSRF" \
   -H "Origin: $STUDIO_URL" -H "Referer: $STUDIO_URL/" -H "Accept: application/json" -H "Content-Type: application/json")
UNIT="block-v1:acme+DATA101+2026-T1+type@vertical+block@645f5ded5f544adab9fb603c4afc3bac"

HTML=$(curl "${S[@]}" -X POST "$STUDIO_URL/xblock/" -d "{\"parent_locator\":\"$UNIT\",\"category\":\"html\"}" \
  | python3 -c 'import sys,json; print(json.load(sys.stdin)["locator"])')

# Build the body in a file so quotes and newlines survive; send it as JSON.
cat > body.html <<'HTML'
<section>
  <h3>Why data matters</h3>
  <p>Every decision in this course starts with a question and ends with evidence.</p>
  <div style="border-left:4px solid #0058cc;background:#f3f7ff;padding:12px 16px;margin:16px 0;border-radius:6px;">
    <strong>Key idea.</strong> A number without a question is noise; a question without a number is a guess.
  </div>
  <img src="/static/decision-loop.png" alt="The question → data → decision loop" width="640">
  <ol><li>Ask</li><li>Measure</li><li>Decide</li></ol>
</section>
HTML
python3 -c 'import json,sys; print(json.dumps({"data": open("body.html").read(), "metadata": {"display_name": "Why data matters"}}))' \
  | curl "${S[@]}" -X POST "$STUDIO_URL/xblock/$HTML" -d @-
```

## Authoring rules

**The bar:** every block is well written, presentable and beautiful,
informative without being distracting, structured and reviewed. Written by a
sub-agent? It must follow the same content brief as every other block
(`/iblai-api-studio` "Content quality"); review it for voice, depth (no
placeholder or padding text, no unit under ~150 words of real content),
heading levels, the same callout/card patterns as its neighbours, and a real
title — before posting, not after.

**What the LMS owns — never override:** font family, base font size, line
height, text colour of body copy, and the component's width. No `font-family`,
`font-size` on body text, `max-width`/`width` on the outer wrapper, no
`margin: 0 auto` centring, no `<style>` blocks, `<script>`, `<html>`/`<head>`/`<body>`.
The LMS app themes the page and adapts it to phones; a component that pins its
own width or type breaks that.

**What you own — use inline CSS to make content look designed:** structure and
emphasis inside the component. Wrap every component in one `<section>` (or
`<div>`), then build with these patterns, keeping colours to a small palette
(brand blue `#0058cc`, neutral greys, one accent for warnings):

| Pattern | Markup |
|---|---|
| Callout / key idea | `<div style="border-left:4px solid #0058cc;background:#f3f7ff;padding:12px 16px;border-radius:6px;margin:16px 0;">…</div>` |
| Warning / common mistake | same, `border-left-color:#b45309;background:#fff7ed;` |
| Card grid (2–3 concepts) | `<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px;"><div style="border:1px solid #e5e7eb;border-radius:8px;padding:14px;"><h4 style="margin-top:0;">Title</h4><p>…</p></div>…</div>` |
| Definition / step list | `<ol>` with `<li><strong>Step name.</strong> detail</li>` |
| Comparison table | `<table style="border-collapse:collapse;width:100%;"><thead><tr><th scope="col" style="text-align:left;border-bottom:2px solid #e5e7eb;padding:8px;">…</th></tr></thead><tbody><tr><td style="border-bottom:1px solid #e5e7eb;padding:8px;">…</td></tr></tbody></table>` |
| Tooltip / glossary term | `<abbr title="Full explanation">term</abbr>` or `<span title="…" style="border-bottom:1px dotted;">term</span>` |
| Hierarchy inside a component | `<h3>` for the component's topic, `<h4>`/`<h5>` for parts; never `<h1>`/`<h2>` |
| Emphasis | `<strong>` for terms, `<em>` for nuance; colour only as a secondary cue |

Use `width:100%` only *inside* the component (tables, images, iframes) — it
means "fill whatever the LMS gives me", not "set the page width".

**Spacing — the difference between a wall of text and a page:**
- One idea per paragraph, 2–4 sentences; a `<p>` per paragraph, never `<br>` to fake spacing.
- A heading (`<h3>`/`<h4>`) every 150–300 words; leave the LMS's own heading margins alone.
- Vertical rhythm with `margin:16px 0` on callouts, tables, images and card grids (`24px 0` before a new `<h3>` block if it follows a dense element).
- Padding inside boxes (`12px 16px` callouts, `14px` cards, `8px` table cells); nothing inside a box touches its border.
- Lists for anything enumerable; a blank line's worth of space (`margin-bottom:12px`) after a list before prose resumes.
- Media on its own line with space around it (`display:block;margin:16px auto;` on images).
- No empty `<p></p>` or `&nbsp;` spacers — they render inconsistently across devices.

**Images and files:** upload with `POST /assets/{course_key}/` and reference the
`portable_url` (`/static/<filename>`) — Studio rewrites it on both hosts. Always
set `alt` (empty `alt=""` for decorative) and `width`/`height` when known.

**Video:** `<div style="aspect-ratio:16/9;"><iframe style="width:100%;height:100%;border:0;" src="https://www.youtube.com/embed/<id>" title="…" allowfullscreen loading="lazy"></iframe></div>`.

**Links:** external `target="_blank" rel="noopener"`; other course pages via the
block's `lms_url` or `/jump_to_id/<block_id>` (relative, survives reruns).

**Accessibility:** one idea per paragraph, real lists for lists, tables only
for tabular data with `<th scope="col">`, ≥ 4.5:1 contrast on anything
coloured, no meaning by colour alone, headings in order.

**Size and validity:** under ~30 KB per component **including inline SVG and
any `data:` image URIs** — an inline chart or diagram easily runs to hundreds
of KB and is the usual way this limit is blown. Upload images and SVGs as
course assets (`POST /assets/{course_key}/`) and reference `/static/<file>`;
split long readings across components or units. Studio stores exactly what you
send, so validate the fragment yourself — one unclosed tag breaks the unit's
layout. `\( … \)` /
`\[ … \]` LaTeX is rendered by MathJax.

## Notes

- `display_name` defaults to `"Text"` when never set (the bulk builder in `/iblai-api-studio-outline` leaves it so) — give every block a title; it shows in the page header and analytics.
- Updating `data` on a published block makes the unit `has_changes: true`; republish the unit.
- The stored HTML is returned verbatim by `GET /xblock/{html}` — read before a partial edit and resend the full body.
- One html block per idea; several html blocks in a unit are fine (unlike problem blocks — see `/iblai-api-studio-problem`).
- Boilerplates other than `announcement.yaml` exist upstream (`raw.yaml`, `latex_html.yaml`, `zooming_image.yaml`) but only `announcement.yaml` is verified here; an unknown name creates a blank block without error.

Attribution

iblaiiblai
View sourceMore from iblai →
SSkills DirectorySkills Directory

Know which skills are safe — weekly.

Best new skills + every skill we flagged as malicious. From the team that scanned 103,619.

Join free

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Know which skills are safe — weekly.

Best new skills + every skill we flagged as malicious. From the team that scanned 103,619.

Join free

Related Skills

Browser Extension Developer

Use this skill when developing or maintaining browser extension code in the `browser/` directory, including Chrome/Firefox/Edge compatibility, content scripts, background scripts, or i18n updates.

281612 votes

Seo Optimizer

SEO optimization with keyword analysis, readability assessment, technical validation, content quality. Use for search rankings, blog posts, content audits, or encountering keyword density, readability scores, meta tags, schema markup errors.

2132 votes

Google Official Seo Guide

Official Google SEO guide covering search optimization, best practices, Search Console, crawling, indexing, and improving website search visibility based on official Google documentation

1862 votes

Tanstack Start

Build a full-stack TanStack Start app on Cloudflare Workers from scratch — SSR, file-based routing, server functions, D1+Drizzle, better-auth, Tailwind v4+shadcn/ui. Use whenever the user mentions TanStack Start, asks to scaffold a full-stack Cloudflare app with SSR, wants an SSR dashboard, or asks for a React 19 + Cloudflare Workers app with file-based routing and server functions — even if they don't name TanStack Start specifically. No template repo — Claude generates every file fresh per ...

9881 votes

Pentest

PTES-aligned adversarial security audit for backend, frontend, and mobile applications. Produces a CVSS-scored Hacker Report with verified PoCs and phased remediation.

5491 votes
View all in development →