mirror of
https://github.com/edufeed-org/nips.git
synced 2025-12-09 16:24:32 +00:00
fix language specs, remove bloating pseudocode
This commit is contained in:
parent
30aea8c65f
commit
c55b4e503b
1 changed files with 17 additions and 344 deletions
361
edufeed.md
361
edufeed.md
|
|
@ -59,9 +59,8 @@ This is how we convert each property of the AMB:
|
||||||
- `description` → `["description", <value>]`
|
- `description` → `["description", <value>]`
|
||||||
- `about` (array of concept objects) → Repeat for each:
|
- `about` (array of concept objects) → Repeat for each:
|
||||||
- `["about:id", <uri>]`
|
- `["about:id", <uri>]`
|
||||||
- `["about:prefLabel", <label>]`
|
- `["about:prefLabel:lang", <label>]`
|
||||||
- `["about:type", "Concept"]`
|
- `["about:type", "Concept"]`
|
||||||
- `["about:inLanguage", <language>]` (if applicable)
|
|
||||||
- `keywords` → `["t", <keyword>]` (repeat for each keyword, using Nostr `t` tag)
|
- `keywords` → `["t", <keyword>]` (repeat for each keyword, using Nostr `t` tag)
|
||||||
- `inLanguage` → `["inLanguage", <languageCode>]` (repeat for each language)
|
- `inLanguage` → `["inLanguage", <languageCode>]` (repeat for each language)
|
||||||
- `image` → `["image", <uri>]`
|
- `image` → `["image", <uri>]`
|
||||||
|
|
@ -106,41 +105,36 @@ This is how we convert each property of the AMB:
|
||||||
- `["license:id", <license_uri>]`
|
- `["license:id", <license_uri>]`
|
||||||
- `conditionsOfAccess` (Concept object) →
|
- `conditionsOfAccess` (Concept object) →
|
||||||
- `["conditionsOfAccess:id", <uri>]`
|
- `["conditionsOfAccess:id", <uri>]`
|
||||||
- `["conditionsOfAccess:prefLabel", <label>]` (optional)
|
- `["conditionsOfAccess:prefLabel:lang", <label>]` (optional)
|
||||||
- `["conditionsOfAccess:type", "Concept"]` (optional)
|
- `["conditionsOfAccess:type", "Concept"]` (optional)
|
||||||
- `["conditionsOfAccess:inLanguage", <language>]` (optional)
|
|
||||||
|
|
||||||
**Educational:**
|
**Educational:**
|
||||||
|
|
||||||
- `learningResourceType` (array of Concept objects) → Repeat for each:
|
- `learningResourceType` (array of Concept objects) → Repeat for each:
|
||||||
- `["learningResourceType:id", <uri>]`
|
- `["learningResourceType:id", <uri>]`
|
||||||
- `["learningResourceType:prefLabel", <label>]` (optional)
|
- `["learningResourceType:prefLabel:lang", <label>]` (optional)
|
||||||
- `["learningResourceType:type", "Concept"]` (optional)
|
- `["learningResourceType:type", "Concept"]` (optional)
|
||||||
- `["learningResourceType:inLanguage", <language>]` (optional)
|
|
||||||
- `audience` (array of Concept objects) → Repeat for each:
|
- `audience` (array of Concept objects) → Repeat for each:
|
||||||
- `["audience:id", <uri>]`
|
- `["audience:id", <uri>]`
|
||||||
- `["audience:prefLabel", <label>]` (optional)
|
- `["audience:prefLabel:lang", <label>]` (optional)
|
||||||
- `["audience:type", "Concept"]` (optional)
|
- `["audience:type", "Concept"]` (optional)
|
||||||
- `["audience:inLanguage", <language>]` (optional)
|
|
||||||
- `teaches` (array of Concept objects) → Repeat for each:
|
- `teaches` (array of Concept objects) → Repeat for each:
|
||||||
- `["teaches:id", <uri>]`
|
- `["teaches:id", <uri>]`
|
||||||
- `["teaches:prefLabel", <label>]` (optional)
|
- `["teaches:prefLabel:lang", <label>]` (optional)
|
||||||
- `assesses` (array of Concept objects) → Repeat for each:
|
- `assesses` (array of Concept objects) → Repeat for each:
|
||||||
- `["assesses:id", <uri>]`
|
- `["assesses:id", <uri>]`
|
||||||
- `["assesses:prefLabel", <label>]` (optional)
|
- `["assesses:prefLabel:lang", <label>]` (optional)
|
||||||
- `competencyRequired` (array of Concept objects) → Repeat for each:
|
- `competencyRequired` (array of Concept objects) → Repeat for each:
|
||||||
- `["competencyRequired:id", <uri>]`
|
- `["competencyRequired:id", <uri>]`
|
||||||
- `["competencyRequired:prefLabel", <label>]` (optional)
|
- `["competencyRequired:prefLabel:lang", <label>]` (optional)
|
||||||
- `educationalLevel` (array of Concept objects) → Repeat for each:
|
- `educationalLevel` (array of Concept objects) → Repeat for each:
|
||||||
- `["educationalLevel:id", <uri>]`
|
- `["educationalLevel:id", <uri>]`
|
||||||
- `["educationalLevel:prefLabel", <label>]` (optional)
|
- `["educationalLevel:prefLabel:lang", <label>]` (optional)
|
||||||
- `["educationalLevel:type", "Concept"]` (optional)
|
- `["educationalLevel:type", "Concept"]` (optional)
|
||||||
- `["educationalLevel:inLanguage", <language>]` (optional)
|
|
||||||
- `interactivityType` (Concept object) →
|
- `interactivityType` (Concept object) →
|
||||||
- `["interactivityType:id", <uri>]`
|
- `["interactivityType:id", <uri>]`
|
||||||
- `["interactivityType:prefLabel", <label>]` (optional)
|
- `["interactivityType:prefLabel:lang", <label>]` (optional)
|
||||||
- `["interactivityType:type", "Concept"]` (optional)
|
- `["interactivityType:type", "Concept"]` (optional)
|
||||||
- `["interactivityType:inLanguage", <language>]` (optional)
|
|
||||||
|
|
||||||
**Relations:**
|
**Relations:**
|
||||||
|
|
||||||
|
|
@ -190,218 +184,6 @@ This is how we convert each property of the AMB:
|
||||||
- `["caption:encodingFormat", <format>]` (optional, IANA media type)
|
- `["caption:encodingFormat", <format>]` (optional, IANA media type)
|
||||||
- `["caption:inLanguage", <languageCode>]` (optional)
|
- `["caption:inLanguage", <languageCode>]` (optional)
|
||||||
|
|
||||||
## Conversion Guidelines
|
|
||||||
|
|
||||||
### AMB → Nostr Event (JavaScript)
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
function flattenAMBToNostrTags(ambData) {
|
|
||||||
const tags = [];
|
|
||||||
|
|
||||||
function addTag(key, value) {
|
|
||||||
if (value !== null && value !== undefined && value !== '') {
|
|
||||||
tags.push([key, String(value)]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function flattenObject(obj, prefix = '') {
|
|
||||||
for (const [key, value] of Object.entries(obj)) {
|
|
||||||
const fullKey = prefix ? `${prefix}:${key}` : key;
|
|
||||||
|
|
||||||
// Special case: id maps to 'd' tag
|
|
||||||
if (key === 'id' && !prefix) {
|
|
||||||
addTag('d', value);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Special case: keywords map to 't' tags (Nostr-native)
|
|
||||||
if (key === 'keywords' && !prefix && Array.isArray(value)) {
|
|
||||||
value.forEach(keyword => {
|
|
||||||
addTag('t', keyword);
|
|
||||||
});
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Array.isArray(value)) {
|
|
||||||
// Arrays: repeat the same key for each element
|
|
||||||
value.forEach(item => {
|
|
||||||
if (typeof item === 'object' && item !== null) {
|
|
||||||
flattenObject(item, fullKey);
|
|
||||||
} else {
|
|
||||||
addTag(fullKey, item);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if (typeof value === 'object' && value !== null) {
|
|
||||||
// Nested objects: flatten recursively
|
|
||||||
flattenObject(value, fullKey);
|
|
||||||
} else {
|
|
||||||
// Simple values
|
|
||||||
addTag(fullKey, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
flattenObject(ambData);
|
|
||||||
return tags;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Example usage:
|
|
||||||
const ambMetadata = {
|
|
||||||
id: "https://example.org/resource/123",
|
|
||||||
name: "Introduction to Physics",
|
|
||||||
creator: [
|
|
||||||
{
|
|
||||||
name: "Dr. Jane Smith",
|
|
||||||
type: "Person",
|
|
||||||
affiliation: {
|
|
||||||
name: "MIT",
|
|
||||||
type: "Organization"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
keywords: ["Physics", "Education"]
|
|
||||||
};
|
|
||||||
|
|
||||||
const tags = flattenAMBToNostrTags(ambMetadata);
|
|
||||||
// Result (using Nostr-native conventions):
|
|
||||||
// [
|
|
||||||
// ["d", "https://example.org/resource/123"],
|
|
||||||
// ["name", "Introduction to Physics"],
|
|
||||||
// ["creator:name", "Dr. Jane Smith"],
|
|
||||||
// ["creator:type", "Person"],
|
|
||||||
// ["creator:affiliation:name", "MIT"],
|
|
||||||
// ["creator:affiliation:type", "Organization"],
|
|
||||||
// ["t", "Physics"],
|
|
||||||
// ["t", "Education"]
|
|
||||||
// ]
|
|
||||||
//
|
|
||||||
// Note: If creator had Nostr identity, would also include:
|
|
||||||
// ["p", "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", "wss://relay.example.com", "creator"]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Nostr Event → AMB Metadata (JavaScript)
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
function unflattenNostrTagsToAMB(tags) {
|
|
||||||
const result = {};
|
|
||||||
|
|
||||||
// Group tags by their key
|
|
||||||
const tagGroups = {};
|
|
||||||
const pTags = []; // Collect p tags separately
|
|
||||||
|
|
||||||
tags.forEach(([key, ...values]) => {
|
|
||||||
// Special case: 'd' tag maps to 'id'
|
|
||||||
if (key === 'd') {
|
|
||||||
result.id = values[0];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Special case: 'p' tags with 'creator' marker map to creator.id
|
|
||||||
if (key === 'p') {
|
|
||||||
const [pubkey, relay, marker] = values;
|
|
||||||
if (marker === 'creator' || marker === 'contributor') {
|
|
||||||
pTags.push({ pubkey, relay, marker });
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Special case: 't' tags map to 'keywords'
|
|
||||||
if (key === 't') {
|
|
||||||
if (!result.keywords) {
|
|
||||||
result.keywords = [];
|
|
||||||
}
|
|
||||||
result.keywords.push(values[0]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!tagGroups[key]) {
|
|
||||||
tagGroups[key] = [];
|
|
||||||
}
|
|
||||||
tagGroups[key].push(values);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Process p tags (creator/contributor)
|
|
||||||
if (pTags.length > 0) {
|
|
||||||
result.creator = pTags.map(({ pubkey }) => ({
|
|
||||||
id: pubkey
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process each tag group
|
|
||||||
for (const [key, valuesList] of Object.entries(tagGroups)) {
|
|
||||||
const parts = key.split(':');
|
|
||||||
|
|
||||||
// Multiple occurrences of same key = array
|
|
||||||
if (valuesList.length > 1) {
|
|
||||||
// Check if this is an object array (has nested properties)
|
|
||||||
const hasNestedProps = Object.keys(tagGroups).some(k =>
|
|
||||||
k.startsWith(key + ':')
|
|
||||||
);
|
|
||||||
|
|
||||||
if (hasNestedProps) {
|
|
||||||
// Array of objects - reconstruct each object
|
|
||||||
const arrayResult = [];
|
|
||||||
valuesList.forEach(values => {
|
|
||||||
const obj = {};
|
|
||||||
setNestedValue(obj, parts, values[0]);
|
|
||||||
arrayResult.push(obj);
|
|
||||||
});
|
|
||||||
setNestedValue(result, parts, arrayResult);
|
|
||||||
} else {
|
|
||||||
// Simple array
|
|
||||||
setNestedValue(result, parts, valuesList.map(v => v[0]));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Single occurrence
|
|
||||||
setNestedValue(result, parts, valuesList[0][0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function setNestedValue(obj, parts, value) {
|
|
||||||
const lastPart = parts[parts.length - 1];
|
|
||||||
let current = obj;
|
|
||||||
|
|
||||||
for (let i = 0; i < parts.length - 1; i++) {
|
|
||||||
if (!current[parts[i]]) {
|
|
||||||
current[parts[i]] = {};
|
|
||||||
}
|
|
||||||
current = current[parts[i]];
|
|
||||||
}
|
|
||||||
|
|
||||||
current[lastPart] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Example usage:
|
|
||||||
const nostrTags = [
|
|
||||||
["d", "https://example.org/resource/123"],
|
|
||||||
["name", "Introduction to Physics"],
|
|
||||||
["p", "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", "wss://relay.example.com", "creator"],
|
|
||||||
["creator:affiliation:name", "MIT"],
|
|
||||||
["creator:affiliation:type", "Organization"],
|
|
||||||
["t", "Physics"],
|
|
||||||
["t", "Education"]
|
|
||||||
];
|
|
||||||
|
|
||||||
const ambMetadata = unflattenNostrTagsToAMB(nostrTags);
|
|
||||||
// Result:
|
|
||||||
// {
|
|
||||||
// id: "https://example.org/resource/123",
|
|
||||||
// name: "Introduction to Physics",
|
|
||||||
// creator: {
|
|
||||||
// // Note: p tag is decoded to get the pubkey
|
|
||||||
// id: "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
|
|
||||||
// affiliation: {
|
|
||||||
// name: "MIT",
|
|
||||||
// type: "Organization"
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// keywords: ["Physics", "Education"]
|
|
||||||
// }
|
|
||||||
```
|
|
||||||
|
|
||||||
## How to convert an AMB nostr-event to AMB metadata
|
## How to convert an AMB nostr-event to AMB metadata
|
||||||
|
|
||||||
To convert a Nostr event back to AMB metadata:
|
To convert a Nostr event back to AMB metadata:
|
||||||
|
|
@ -416,93 +198,6 @@ To convert a Nostr event back to AMB metadata:
|
||||||
- Convert string booleans to actual booleans
|
- Convert string booleans to actual booleans
|
||||||
- Parse ISO8601 dates if needed for validation
|
- Parse ISO8601 dates if needed for validation
|
||||||
|
|
||||||
### Reconstruction Algorithm
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
function reconstructAMB(nostrEvent) {
|
|
||||||
const amb = {
|
|
||||||
"@context": [
|
|
||||||
"https://w3id.org/kim/amb/context.jsonld",
|
|
||||||
{ "@language": "de" }
|
|
||||||
],
|
|
||||||
type: ["LearningResource"]
|
|
||||||
};
|
|
||||||
|
|
||||||
// Group tags by their base key (before first ':')
|
|
||||||
const tagsByBase = {};
|
|
||||||
nostrEvent.tags.forEach(tag => {
|
|
||||||
const [key, ...values] = tag;
|
|
||||||
const baseKey = key.split(':')[0];
|
|
||||||
|
|
||||||
if (!tagsByBase[baseKey]) {
|
|
||||||
tagsByBase[baseKey] = [];
|
|
||||||
}
|
|
||||||
tagsByBase[baseKey].push({ fullKey: key, values });
|
|
||||||
});
|
|
||||||
|
|
||||||
// Reconstruct each property
|
|
||||||
for (const [baseKey, tags] of Object.entries(tagsByBase)) {
|
|
||||||
if (baseKey === 'd') {
|
|
||||||
amb.id = tags[0].values[0];
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if this is a simple property or nested
|
|
||||||
const hasNested = tags.some(t => t.fullKey.includes(':'));
|
|
||||||
|
|
||||||
if (!hasNested) {
|
|
||||||
// Simple property
|
|
||||||
if (tags.length === 1) {
|
|
||||||
amb[baseKey] = tags[0].values[0];
|
|
||||||
} else {
|
|
||||||
// Multiple values = array
|
|
||||||
amb[baseKey] = tags.map(t => t.values[0]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Nested property - group by instance
|
|
||||||
amb[baseKey] = reconstructNestedProperty(tags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return amb;
|
|
||||||
}
|
|
||||||
|
|
||||||
function reconstructNestedProperty(tags) {
|
|
||||||
// Group tags that belong to the same array instance
|
|
||||||
const instances = [];
|
|
||||||
let currentInstance = {};
|
|
||||||
let lastDepth = 0;
|
|
||||||
|
|
||||||
tags.forEach(tag => {
|
|
||||||
const parts = tag.fullKey.split(':');
|
|
||||||
const depth = parts.length;
|
|
||||||
|
|
||||||
// If depth decreased, we're starting a new instance
|
|
||||||
if (depth <= lastDepth && Object.keys(currentInstance).length > 0) {
|
|
||||||
instances.push(currentInstance);
|
|
||||||
currentInstance = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build nested structure
|
|
||||||
let current = currentInstance;
|
|
||||||
for (let i = 1; i < parts.length - 1; i++) {
|
|
||||||
if (!current[parts[i]]) {
|
|
||||||
current[parts[i]] = {};
|
|
||||||
}
|
|
||||||
current = current[parts[i]];
|
|
||||||
}
|
|
||||||
current[parts[parts.length - 1]] = tag.values[0];
|
|
||||||
|
|
||||||
lastDepth = depth;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (Object.keys(currentInstance).length > 0) {
|
|
||||||
instances.push(currentInstance);
|
|
||||||
}
|
|
||||||
|
|
||||||
return instances.length === 1 ? instances[0] : instances;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## How to query for AMB nostr-events in supporting relays
|
## How to query for AMB nostr-events in supporting relays
|
||||||
|
|
||||||
|
|
@ -532,17 +227,14 @@ Query capabilities should include:
|
||||||
["name", "Pythagorean Theorem Video"],
|
["name", "Pythagorean Theorem Video"],
|
||||||
["description", "An introductory video explaining the Pythagorean theorem"],
|
["description", "An introductory video explaining the Pythagorean theorem"],
|
||||||
["about:id", "http://w3id.org/kim/schulfaecher/s1017"],
|
["about:id", "http://w3id.org/kim/schulfaecher/s1017"],
|
||||||
["about:prefLabel", "Mathematik"],
|
["about:prefLabel:de", "Mathematik"],
|
||||||
["about:type", "Concept"],
|
["about:type", "Concept"],
|
||||||
["about:inLanguage", "de"],
|
|
||||||
["about:id", "http://w3id.org/kim/schulfaecher/s1005"],
|
["about:id", "http://w3id.org/kim/schulfaecher/s1005"],
|
||||||
["about:prefLabel", "Deutsch"],
|
["about:prefLabel:de", "Deutsch"],
|
||||||
["about:type", "Concept"],
|
["about:type", "Concept"],
|
||||||
["about:inLanguage", "de"],
|
|
||||||
["learningResourceType:id", "http://w3id.org/openeduhub/vocabs/new_lrt/7a6e9608-2554-4981-95dc-47ab9ba924de"],
|
["learningResourceType:id", "http://w3id.org/openeduhub/vocabs/new_lrt/7a6e9608-2554-4981-95dc-47ab9ba924de"],
|
||||||
["learningResourceType:prefLabel", "Video"],
|
["learningResourceType:prefLabel:de", "Video"],
|
||||||
["learningResourceType:type", "Concept"],
|
["learningResourceType:type", "Concept"],
|
||||||
["learningResourceType:inLanguage", "de"],
|
|
||||||
["t", "Pythagoras"],
|
["t", "Pythagoras"],
|
||||||
["t", "Geometrie"],
|
["t", "Geometrie"],
|
||||||
["t", "Mathematik"],
|
["t", "Mathematik"],
|
||||||
|
|
@ -587,15 +279,15 @@ Query capabilities should include:
|
||||||
["dateCreated", "2024-01-15"],
|
["dateCreated", "2024-01-15"],
|
||||||
["datePublished", "2024-02-01"],
|
["datePublished", "2024-02-01"],
|
||||||
["about:id", "https://w3id.org/kim/hochschulfaechersystematik/n079"],
|
["about:id", "https://w3id.org/kim/hochschulfaechersystematik/n079"],
|
||||||
["about:prefLabel", "Informatik"],
|
["about:prefLabel:de", "Informatik"],
|
||||||
["about:type", "Concept"],
|
["about:type", "Concept"],
|
||||||
["learningResourceType:id", "https://w3id.org/kim/hcrt/course"],
|
["learningResourceType:id", "https://w3id.org/kim/hcrt/course"],
|
||||||
["learningResourceType:prefLabel", "Course"],
|
["learningResourceType:prefLabel:de", "Kurs"],
|
||||||
["audience:id", "http://purl.org/dcx/lrmi-vocabs/educationalAudienceRole/student"],
|
["audience:id", "http://purl.org/dcx/lrmi-vocabs/educationalAudienceRole/student"],
|
||||||
["audience:prefLabel", "student"],
|
["audience:prefLabel:de", "Student"],
|
||||||
["audience:type", "Concept"],
|
["audience:type", "Concept"],
|
||||||
["educationalLevel:id", "https://w3id.org/kim/educationalLevel/level_06"],
|
["educationalLevel:id", "https://w3id.org/kim/educationalLevel/level_06"],
|
||||||
["educationalLevel:prefLabel", "Bachelor or equivalent"],
|
["educationalLevel:prefLabel:en", "Bachelor or equivalent"],
|
||||||
["inLanguage", "en"],
|
["inLanguage", "en"],
|
||||||
["license:id", "https://creativecommons.org/licenses/by-sa/4.0/"],
|
["license:id", "https://creativecommons.org/licenses/by-sa/4.0/"],
|
||||||
["isAccessibleForFree", "true"]
|
["isAccessibleForFree", "true"]
|
||||||
|
|
@ -607,17 +299,6 @@ Query capabilities should include:
|
||||||
|
|
||||||
## Tools
|
## Tools
|
||||||
|
|
||||||
### Decoding Nostr Identifiers with njump
|
|
||||||
|
|
||||||
[`njump`](https://njump.me/) is a helpful tool for decoding and navigating Nostr identifiers, particularly useful when working with `p` tags (pubkeys) and `a` tags (addressable events):
|
|
||||||
|
|
||||||
- **For `p` tag pubkeys**: Paste the hex pubkey or npub identifier at `https://njump.me/<pubkey-or-npub>` to view the profile and see all resources published by that user
|
|
||||||
- Example: `https://njump.me/79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798`
|
|
||||||
- Or: `https://njump.me/npub1...`
|
|
||||||
|
|
||||||
- **For `a` tag addressable events**: Use `https://njump.me/naddr1...` to view the specific event
|
|
||||||
- Example: `https://njump.me/naddr1qqqgcjsyup9qqqg6cjv` to navigate to an addressable resource
|
|
||||||
|
|
||||||
### Using `nak` to create AMB events
|
### Using `nak` to create AMB events
|
||||||
|
|
||||||
You can use [`nak`](https://github.com/fiatjaf/nak) to create AMB events with the flattened tag structure:
|
You can use [`nak`](https://github.com/fiatjaf/nak) to create AMB events with the flattened tag structure:
|
||||||
|
|
@ -631,9 +312,8 @@ nak event \
|
||||||
--tag name="Pythagorean Theorem Video" \
|
--tag name="Pythagorean Theorem Video" \
|
||||||
--tag description="An introductory video" \
|
--tag description="An introductory video" \
|
||||||
--tag about:id="http://w3id.org/kim/schulfaecher/s1017" \
|
--tag about:id="http://w3id.org/kim/schulfaecher/s1017" \
|
||||||
--tag about:prefLabel="Mathematik" \
|
--tag about:prefLabel:de="Mathematik" \
|
||||||
--tag about:type="Concept" \
|
--tag about:type="Concept" \
|
||||||
--tag about:inLanguage="de" \
|
|
||||||
--tag t="Pythagoras" \
|
--tag t="Pythagoras" \
|
||||||
--tag t="Geometrie" \
|
--tag t="Geometrie" \
|
||||||
--tag inLanguage="de" \
|
--tag inLanguage="de" \
|
||||||
|
|
@ -648,13 +328,6 @@ nak event \
|
||||||
--tag creator:affiliation:name="MIT" \
|
--tag creator:affiliation:name="MIT" \
|
||||||
--tag creator:affiliation:type="Organization"
|
--tag creator:affiliation:type="Organization"
|
||||||
|
|
||||||
# Example 3: Resource with relation to another AMB event (using a tag)
|
|
||||||
nak event \
|
|
||||||
--kind 30142 \
|
|
||||||
--tag d="https://example.org/resource/789" \
|
|
||||||
--tag name="Physics Module Part 1" \
|
|
||||||
--tag a="30142:79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798:physics-course;wss://relay.example.com;isPartOf"
|
|
||||||
```
|
|
||||||
|
|
||||||
## References
|
## References
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue