1.0.1 • Published 2 months ago

raven-writer v1.0.1

Weekly downloads
-
License
ISC
Repository
-
Last release
2 months ago

raven-writer

raven-writer is a FE utility to allow for easy translations and interpolations for projects using the popular POEditor localization service.

What raven-writer does:

  • GETs and caches localizations for your project
  • Refreshes those localizations at a given interval
  • Transforms simple markdown in your content into HTML strings
  • Allows for dynamic interpolation of string values into your content
  • Easily gets values by term

Docs

Install

npm install raven-writer -S

Quick start example

Given the following POEditor project

In our project we have:

  • A language that is American english, which has a ISO 639-1 language code of en-us
  • A term MY_KEY that has a content value of "My value"
  • A second term GREETING that has a content value of "Hello, **{{name}}!**"
    • Note that the value has {{}} to denote an interpolated value with the key name
    • It also has ** markdown indicating it should be bolded
import { Raven } from "raven-writer";

// make the POE instance
const POE = new Raven();

// load localizations into the instance
await POE.fetchLocalizations({
  id: "<POEDITOR_PROJECT_ID>",
  token: "<YOUR_READ_ONLY_POEDITOR_API_TOKEN>",
  languages: ["en-us"]
});

// make a dictionary
const Translate = POE.makeDictionary("en-us");

// Logs: "My value"
console.log(Translate("MY_KEY"));

// Logs: "Hello, <b>Nate!</b>"
console.log(Translate("GREETING", {name: "Nate"}));

Instantiation

In most cases you'll instantiate the POE instance simply by calling new Raven().

You can optionally pre-load the POE instance with localizations. You'd do this if you wanted access to the POE.makeDictionary(language) functionality without having to make API calls. Refer to the localizations structure if you want to do this.

Props

PropTypeRequired?Description
localizationsObjectThe preloaded localizations

Returns

A POE instance that has the following methods:

POE.getLocalizations(localizations);
POE.fetchLocalizations({id, token, languages, keepAlive, url});
POE.makeDictionary(language);
POE.makeText(string, interpolations);
POE.kill();

Usage

Most common case

import { Raven } from "raven-writer";
const POE = new Raven();

Optional preloading

import { Raven } from "raven-writer";

const localizations = {
  "en-us": {
    "GREETING": "Hi!"
  }
};

const PRELOADED = new Raven(localizations);
const Translate = POE.makeDictionary("en-us");
console.log(Translate("GREETING")); // Logs: "Hi!"

POE.fetchLocalizations({...})

Fetches and catches localizations.

Props

PropTypeRequired?Description
tokenStringif url is undefinedThe readonly api_token found in your POEditor acct
idStringif url is undefinedThe project id found in your POEditor acct
languagesArray of ISO 639-1 language codesif url is undefinedThe languages you want to fetch for the given project
keepAliveIntegerIf present the localizations will be refreshed per milliseconds defined this value
urlStringif url, id, and languages are undefinedIf present calls will be made to that url instead of hitting the POEditor endpoint

Returns

A promise that once resolved will populate the POE instance with localizations.

Usage

Most common usage

import { Raven } from "raven-writer";
const tenMins = 1000 * 60 * 10;
const POE = new Raven();
await POE.fetchLocalizations({
  id: "<POEDITOR_PROJECT_ID>",
  token: "<YOUR_READ_ONLY_POEDITOR_API_TOKEN>",
  languages: ["en-us", "sp_mx"],
  keepAlive: tenMins // optional
});

Overwriting the endpoint

import { Raven } from "raven-writer";
const POE = new Raven();
await POE.fetchLocalizations({
  url: "<YOUR_CUSTOM_GET_ENDPOINT>"
});

Note: the response from your endpoint must have the same structure as the localizations structure

POE.makeDictionary(language)

Makes a Dictionary function for a given language that has already been cached in the POE instance

Props

PropTypeRequired?Description
languageStringyesA ISO 639-1 language code

Returns

A Dictionary function

Usage

import { Raven } from "raven-writer";
const POE = new Raven();
await POE.fetchLocalizations({..., languages: ["en-us", "sp-mx"]});
const enUsDictionary = POE.makeDictionary("en-us");
const spMxDictionary = POE.makeDictionary("sp-mx");

POE.getLocalizations(language)

Returns the raw localizations object. see: localizations structure.

Props

PropTypeRequired?Description
languageStringA ISO 639-1 language code

Returns

A localizations object

Usage

Assume the cached localizations are the following:

{
  "en-us": {
    "GREETING": "Hello"
  },
  "sp-mx": {
    "GREETING": "Hola"
  }
}
import { Raven } from "raven-writer";
const POE = new Raven();
await POE.fetchLocalizations({..., languages: ["en-us", "sp_mx"]});
console.log(POE.getLocalizations()) // Logs the preceding full object
console.log(POE.getLocalizations("sp_mx")) // Logs { GREETING: "Hola" }

POE.makeText(str, interolations)

Adds interpolations and/or Markdown transformed into HTML string to a given string. See: Content markdown and interpolation syntax.

Props

PropTypeRequired?Description
strStringAny string value, ie not a POE term
interolationsObjectAn object with key names that match the dynamic content markers in the str

Returns

A string with interpolations and Markdown transformed into HTML str (if applicable).

Usage

import { Raven } from "raven-writer";
const POE = new Raven();

// Logs: "Plain text"
console.log(POE.makeText("Plain text"));

// Logs: "Hello, Nate"
console.log(POE.makeText("Hello, {{name}}", { name: "Nate" }));

// Logs: "Some <i>italic text</i>"
console.log(POE.makeText("Some *italic text*"));

// Logs: "Hello, <b>Nate</b>"
console.log(POE.makeText("Hello, **{{name}}**", { name: "Nate" }));

POE.kill()

If you call POE.fetchLocalizations({...}) and set it to refresh localizations via keepAlive, this stops all refreshes on that instance.

Returns

undefined

Usage

import { Raven } from "raven-writer";
const tenMins = 1000 * 1000 * 60 * 10;
const POE = new Raven();
await POE.fetchLocalizations({..., keepAlive: tenMins});
...
POE.kill();

Dictionary(term, interpolations)

The function returns the localized content value of a term, optionally with injected interpolations. Markdown is transformed into HTML strings.

Props

PropTypeRequired?Description
termStringAny string value, ie not a POE term
interolationsObjectAn object with key names that match the dynamic content markers for the content value associated with the term

Returns

A string with interpolations and Markdown transformed into HTML str (if applicable) for the language used to create the function.

Usage

import { Raven } from "raven-writer";

const POE = new Raven();
await POE.fetchLocalizations({..., languages: ["en-us", "sp-mx"]});

/*
Assume `POE.fetchLocalizations({...})` caches the following localizations:
{
  "en-us": {
    "GREETING": "*Hello*, {{name}}"
  },
  "sp-mx": {
    "GREETING": "Hola, {{name}}"
  }
}
*/

const EN_US = POE.makeDictionary("en-us");
const SP_MX = POE.makeDictionary("sp-mx");

// Logs: "<i>Hello</i>, Nate"
console.log(EN_US("GREETING", {name: "Nate"}));

// Logs: "Hola, Nate"
console.log(SP_MX("GREETING", {name: "Nate"}));

Content markdown and interpolation syntax

raven-writer supports a limited subset of markdown and a simple way of adding interpolations to your content. Use this as a guide when adding content values on the POEditor dashboard

Supported Markdown

StyleMarkdownOutput
bold**bold**<b>world</b>
italic*italic*<i>italic</i>
bold italic***bold italics***<b><i>bold italic</i></b>
link[link name](https://example.com)<a href="https://example.com" target="_blank">link name</a>

Interpolations

Add variables into your content by using interpolations object. The keys in the interpolations object wrapped between {{ and }} can be used to represent dynamic content.

Localizations structure

The localizations are stored as a single nested object. Top level keys are ISO 639-1 language codes, each holding that language's localizations in key/value pairs where the key is what POEditor refers to as the term and value is what POEditor refers to as the content. See the POEditor API for more details.

Here is an example assuming 3 languages in the project with only one entry in each:

{
  "en-us": {
    "GREETING": "Hello"
  },
  "en-au": {
    "GREETING": "G'day"
  },
  "sp-mx": {
    "GREETING": "Hola"
  }
}
1.0.1

2 months ago

1.0.0

2 months ago