CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-node-json2html

HTML templating in pure javascript that transforms JSON objects into HTML using JavaScript template objects

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

utilities.mddocs/

Utility Functions

Helper functions for text encoding, DOM hydration, component updates, and other common operations that support the json2html templating system.

Capabilities

Text Encoding

Safely encode HTML strings to prevent XSS attacks and ensure proper display of user-generated content.

/**
 * Encodes HTML string to text by escaping HTML entities
 * @param {string|null|undefined} html - HTML string to encode, null, or undefined
 * @returns {string} Text with HTML entities escaped, empty string for null/undefined
 */
function toText(html);

Usage Examples:

const json2html = require('node-json2html');

// Basic HTML encoding
const userInput = '<script>alert("XSS")</script>';
const safe = json2html.toText(userInput);
console.log(safe); 
// Result: "&lt;script&gt;alert(&quot;XSS&quot;)&lt;/script&gt;"

// Handle various data types
console.log(json2html.toText("Hello & goodbye"));  // "Hello &amp; goodbye"
console.log(json2html.toText("<div>content</div>"));  // "&lt;div&gt;content&lt;/div&gt;"
console.log(json2html.toText(null));  // ""
console.log(json2html.toText(undefined));  // ""
console.log(json2html.toText(123));  // "123"

// Use in templates for safe text display
const template = {
  "<>": "div",
  "html": [
    { "<>": "h3", "text": "User Comment" },
    { "<>": "p", "html": json2html.toText("${userComment}") }
  ]
};

const data = { userComment: '<script>malicious()</script>' };
const html = json2html.render(data, template);
// User comment is safely encoded in output

DOM Hydration

Attach events and update triggers to existing DOM elements, typically used after server-side rendering or manual DOM manipulation.

/**
 * Hydrates DOM elements with their events and update triggers
 * @param {Element|Element[]} parent - Element or array of elements to hydrate
 * @param {object} events - Event handlers object from iHTML rendering
 * @param {object} triggers - Update triggers object from iHTML rendering  
 * @returns {object} this for method chaining
 */
function hydrate(parent, events, triggers);

Usage Examples:

// Server-side rendering scenario
const template = {
  "<>": "button",
  "text": "Click me",
  "onclick": function(e) { alert("Clicked!"); },
  "#": "button-trigger"
};

// Get iHTML output with events and triggers
const ihtml = json2html.render({}, template, { output: "ihtml" });

// On the client side, inject the HTML
document.getElementById('container').innerHTML = ihtml.html;

// Then hydrate to attach events and triggers
const element = document.getElementById('container').firstElementChild;
json2html.hydrate(element, ihtml.events, ihtml.triggers);

// Now the button will work with click handlers and update triggers

// Hydrate multiple elements
const elements = document.querySelectorAll('.needs-hydration');
json2html.hydrate(Array.from(elements), ihtml.events, ihtml.triggers);

Component Updates

Trigger dynamic updates of components that have been marked with trigger IDs.

/**
 * Triggers component update by ID
 * @param {string} id - Required trigger ID of component(s) to update
 * @param {object} [obj] - Optional new data object to use for update
 */
function refresh(id, obj);

/**
 * @deprecated Use refresh() instead
 * Legacy alias for refresh function
 */
function trigger(id, obj);

Usage Examples:

// Set up components with trigger IDs
const template = {
  "<>": "div",
  "#": "user-status",  // Trigger ID
  "class": "status-${status}",
  "html": [
    { "<>": "span", "text": "${name}" },
    { "<>": "span", "class": "indicator", "text": "(${status})" }
  ]
};

const users = [
  { name: "Alice", status: "online" },
  { name: "Bob", status: "offline" }
];

// Render with DOM integration
document.getElementById('user-list').json2html(users, template);

// Update all elements with trigger ID "user-status"
setTimeout(() => {
  json2html.refresh("user-status", [
    { name: "Alice", status: "busy" },
    { name: "Bob", status: "online" }
  ]);
}, 3000);

// Update with original data (uses stored reference)
setTimeout(() => {
  users[0].status = "away";
  json2html.refresh("user-status"); // Uses original users array
}, 6000);

// Multiple triggers for different components
const dashboardTemplate = {
  "<>": "div",
  "html": [
    {
      "<>": "div",
      "#": "user-count",
      "text": "Users: ${userCount}"
    },
    {
      "<>": "div", 
      "#": "message-count",
      "text": "Messages: ${messageCount}"
    }
  ]
};

// Update specific parts independently
json2html.refresh("user-count", { userCount: 150 });
json2html.refresh("message-count", { messageCount: 1250 });

Version Information

Access the current version of the json2html library for compatibility checking and debugging.

/**
 * Current version of the json2html library
 * @type {string}
 */
const version: string;

Usage Examples:

const json2html = require('node-json2html');

// Check library version
console.log('json2html version:', json2html.version);  // "3.3.3"

// Version compatibility checking
function checkCompatibility() {
  const requiredVersion = '3.0.0';
  const currentVersion = json2html.version;
  
  if (currentVersion < requiredVersion) {
    throw new Error(`json2html ${requiredVersion} or higher required, found ${currentVersion}`);
  }
}

// Feature detection based on version
function hasFeature(feature) {
  const version = json2html.version;
  const major = parseInt(version.split('.')[0]);
  
  switch (feature) {
    case 'iHTML':
      return major >= 3;
    case 'components':
      return major >= 2;
    default:
      return true;
  }
}

// Debug information
function getDebugInfo() {
  return {
    version: json2html.version,
    userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : 'Node.js',
    timestamp: new Date().toISOString()
  };
}

Error Handling

Utility functions handle various error conditions gracefully and provide meaningful feedback.

/**
 * Common error scenarios and handling
 */
// toText handles null/undefined gracefully
json2html.toText(null);      // Returns ""
json2html.toText(undefined); // Returns ""

// render handles missing data gracefully  
json2html.render(null, template);      // Returns ""
json2html.render(undefined, template); // Returns ""

// refresh handles missing trigger IDs gracefully
json2html.refresh("non-existent-id");  // No error, no action

// hydrate handles missing elements gracefully
json2html.hydrate(null, events, triggers);  // No error, no action

Error Handling Examples:

// Safe rendering with error handling
function safeRender(data, template, options = {}) {
  try {
    if (!data || !template) {
      return '';
    }
    
    return json2html.render(data, template, options);
  } catch (error) {
    console.error('Rendering error:', error);
    return '<div class="error">Rendering failed</div>';
  }
}

// Safe text encoding
function safeText(input) {
  if (input === null || input === undefined) {
    return '';
  }
  
  return json2html.toText(String(input));
}

// Safe component updates with validation
function safeRefresh(triggerId, data) {
  if (!triggerId || typeof triggerId !== 'string') {
    console.warn('Invalid trigger ID provided to refresh');
    return;
  }
  
  try {
    json2html.refresh(triggerId, data);
  } catch (error) {
    console.error('Refresh error:', error);
  }
}

// Safe hydration with element validation
function safeHydrate(elements, events, triggers) {
  if (!elements) {
    return;
  }
  
  const elementArray = Array.isArray(elements) ? elements : [elements];
  const validElements = elementArray.filter(el => el && el.nodeType === Node.ELEMENT_NODE);
  
  if (validElements.length > 0) {
    json2html.hydrate(validElements, events || {}, triggers || {});
  }
}

Performance Considerations

Utility functions are optimized for performance but should be used appropriately for best results.

/**
 * Performance best practices
 */
// Batch refresh operations instead of individual calls
// Good:
json2html.refresh("user-list", updatedUsers);

// Avoid:
users.forEach(user => {
  json2html.refresh("user-" + user.id, user);
});

// Cache encoded text for reuse
const encodedTexts = new Map();
function getCachedText(input) {
  if (!encodedTexts.has(input)) {
    encodedTexts.set(input, json2html.toText(input));
  }
  return encodedTexts.get(input);
}

// Hydrate once after batch DOM updates
const ihtml = json2html.render(data, template, { output: "ihtml" });
container.innerHTML = ihtml.html;
json2html.hydrate(container, ihtml.events, ihtml.triggers);

docs

browser-integration.md

components.md

index.md

rendering.md

utilities.md

tile.json