> ## Documentation Index
> Fetch the complete documentation index at: https://developer.dittowords.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Files

> The file structure of text pulled down via the CLI

## Output Directory

The CLI outputs data from Ditto by writing files to disk. By default, these files are written to a `./ditto`  folder relative to the current working directory, but the location of the output files can be customized by defining the `outDir` property in your config.yml file or by setting the environment variable `DITTO_OUT_DIR`.

## `./ditto` Directory

By default, this directory houses the configuration file (`./ditto/config.yml`) used by the CLI and is also the default write destination for any output files the CLI writes to disk. You can override the default location of the config file by using the `--config` flag when running any command or by setting the environment variable `DITTO_PROJECT_CONFIG_FILE` . Legacy Ditto users can use the config override path to support maintaining separate config files for the legacy and current versions of Ditto within the same application.

If you run the CLI and the resolved config file does not exist, the CLI will automatically create a default config.yml file at the path specified.

## String File Naming Conventions

All string files created will generally adhere to the following template:

```typescript theme={null}
{project_id}___{variant_id}.{extension}
```

* `project_id`: the Developer ID of the project.
* `variant_id`: the Developer ID of a variant or `base` for files generated for non-variant text
* `extension`: the file extension that corresponds to the configured format(s) (e.g., **json**, **xml**, **strings**, **stringsdict**)

If `components` is included in the config, a single, combined file for all fetched components will also be created for each variant with the format `components__{variant_id}.{extension}`.

To keep cross-platform behavior consistent, file names will be fully lowercase, have whitespace replaced with hyphens, and have non-word characters (with the exception of `-` and `_`) removed.

## Format-specific Files

### JSON

If one or more JSON string formats are configured, a series of json files will be generated, on a project-variant/components-variant pair basis. Generally each file will follow the shown format:

```json theme={null}
{
  "text-item-developer-id": "string with {{variableId}} variables escaped",
  ...,
  "text-item-with-plural-dev-id": "string with {{count}} characters",
  "text-item-with-plural-dev-id_other": "string with {{count}} characters",
  "text-item-with-plural-dev-id_one": "string with a character",
	...,
  "welcome": "Hello {{userFirstName}}!"
}
```

Additionally, a `variables.json` file will be generated that contains information about any variables used within the fetched text. The file has the following format:

```json theme={null}
{
  "text-variable-id": {
    "example": "example_value",
    "fallback": "default_value"
  },
  "number-variable-id": {
    "example": "1",
    "fallback": "10"
  },
  "link-variable-id": {
    "text": "URL display text",
    "url": "https://dittowords.com"
  },
  "list-variable-id": ["value1", "value2", "value3"],
  "map-variable-id": {
    "key1": "value1",
    "key2": "value2",
    "key3": "value3"
  }
}
```

### Android XML

If `android` format is configured for an output, a series of `.xml` files will be generated, on a project-variant/components-variant pair basis. Generally each file will follow the shown format:

```xml theme={null}
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
  <string name="text-item-developer-id" ditto_api_id="text-item-developer-id">string with <xliff:g id="variableId" example="example_value">%1$s</xliff:g> variables</string>
  <string name="continue" ditto_api_id="continue">Continue</string>
  <string name="email" ditto_api_id="email">Email</string>
  <string name="hello" ditto_api_id="hello">Hello, <xliff:g id="FirstName" example="John">%1$s</xliff:g></string>
  <string name="log_in" ditto_api_id="log-in">Log In</string>
  <string name="save" ditto_api_id="save">Save</string>
  <string name="submit" ditto_api_id="submit">Submit</string>
  <plurals name="the_one_ring" ditto_api_id="the-one-ring">
    <item quantity="many">The <xliff:g id="count__1" example="4">%1$s</xliff:g> rings to rule them all</item>
    <item quantity="few">A few rings to rule them all</item>
  </plurals>
  <string name="welcome" ditto_api_id="welcome">Welcome, <xliff:g id="FirstName" example="John">%1$s</xliff:g>!</string>
</resources>
```

### iOS Strings

If iOS Strings format is configured, a series of `.strings` files will be generated, on a project-variant/components-variant pair basis. Generally each file will follow the shown format:

```
"text-item-developer-id" = "string with %1$@ variables";

"continue" = "Continue";

"email" = "Email";

"hello" = "Hello, %1$@";

"log-in" = "Log In";

"save" = "Save";

"submit" = "Submit";

"welcome" = "Welcome, %1$@!";
```

### iOS StringsDict

If iOS StringsDict format is configured, a series of `.stringsdict` files will be generated, on a project-variant/components-variant pair basis. Generally each file will follow the shown format:

```xml theme={null}
<?xml version="1.0" encoding="utf-8"?>
<plist version="1.0">
  <dict>
    <key>the-one-ring</key>
    <dict>
        <key>NSStringLocalizedFormatKey</key>
        <string>%1$#@count@</string>
        <key>count</key>
        <dict>
            <key>NSStringFormatSpecTypeKey</key>
            <string>NSStringPluralRuleType</string>
            <key>NSStringFormatValueTypeKey</key>
            <string>d</string>
            <key>one</key>
            <string>The one ring to rule them all</string>
            <key>other</key>
            <string>The %2$@ rings to rule them all</string>
        </dict>
    </dict>
  </dict>
</plist>
```

## Framework-specific Files

Within each output format, an optional `framework` can be provided. The framework generates additional helper files to assist with using the output strings files with common third party libraries. Currently, we support two frameworks: [i18next](https://www.i18next.com/) and [vue-i18n](https://github.com/i18next/i18next-vue) .

### i18next

Formats supported: `JSON`

Supported Properties:

#### `type: “commonjs” | “module” (default “commonjs”)`

By default, additional javascript files will be generated using `commonjs` syntax. This property configures the output to use `commonjs` or `module` syntax in the generated files.

**Details:**

Generates an additional javascript file that imports the generated strings files, and exports an object with the json strings grouped by their variants. If included, components will always be applied last.

```javascript theme={null}
// CommonJS
const exampleProject1Base = require("./example-project-1__root__base.json");
const exampleProject1Spanish = require("./example-project-1__root__spanish.json");
const exampleProject2Base = require("./example-project-2__base.json");
const exampleProject2Spanish = require("./example-project-2__spanish.json");
const componentsBase = require("./components__base.json");
const componentsSpanish = require("./components__spanish.json");

module.exports = {
  base: {
    ...exampleProject1Base,
    ...exampleProject2Base,
    ...componentsBase,
  },
  spanish: {
    ...exampleProject1Spanish,
    ...exampleProject2Spanish,
    ...componentsSpanish,
  },
};

// ESM
import exampleProject1Base from "./example-project-1__root__base.json";
import exampleProject1Spanish from "./example-project-1__root__spanish.json";
import exampleProject2Base from "./example-project-2__base.json";
import exampleProject2Spanish from "./example-project-2__spanish.json";
import componentsBase from "./components__base.json";
import componentsSpanish from "./components__spanish.json";

export default {
  base: {
    ...exampleProject1Base,
    ...exampleProject2Base,
    ...componentsBase,
  },
  spanish: {
    ...exampleProject1Spanish,
    ...exampleProject2Spanish,
    ...componentsSpanish,
  },
};
```

### vue-i18n

Formats supported: `JSON`

Functions very similarly and accepts all the same config properties as the `i18next` framework. The main difference is variable interpolation uses single brackets instead of double.

```typescript theme={null}
{
	"text-item-developer-id": "string with {variableId} variables escaped",
	...,
	"welcome": "Hello {userFirstName}!"
}
```

## Ditto-generated Files

### Ditto.swift

If `iosLocales` is configured at the root level of the project config, a `Ditto.swift` file will be auto-generated in conjunction with the respective locale `.lproj` directories.

```swift theme={null}
import SwiftUI

struct Ditto {
    static func getBundle(_ locale: String? = nil) -> Bundle {
        var bundle: Bundle? = nil
        if (locale != nil) {
            let path = Bundle.main.path(forResource: locale, ofType: "lproj")
            if (path != nil) {
                bundle = Bundle(path: path!)
            }
        }
        return bundle ?? Bundle.main
    }

    /// [Open component in Ditto](http://app.dittowords.com/library?selectedLibraryComponentIds=<component-id>)
    ///
    /// - Returns: The localized string for the Ditto identifier "continue"
    public static func continue(_ localeOverride: String? = nil) -> String {
        String.localizedStringWithFormat(NSLocalizedString("continue", tableName: "components", bundle: getBundle(localeOverride), comment: ""))
    }

    /// [Open component in Ditto](http://app.dittowords.com/library/<folder-id>?selectedLibraryComponentIds=<component-id>)
    ///
    /// - Returns: The localized string for the Ditto identifier "hello"
    public static func hello(_ localeOverride: String? = nil, FirstName: String) -> String {
        String.localizedStringWithFormat(NSLocalizedString("hello", tableName: "components", bundle: getBundle(localeOverride), comment: ""), FirstName)
    }

    struct myDittoProject {
        /// [Open text item in Ditto](http://app.dittowords.com/projects-beta/<project-id>?viewState=text&selectedTextItemIds=<text-item-id>)
        ///
        /// - Returns: The localized string for the Ditto identifier "email"
        public static func email(_ localeOverride: String? = nil) -> String {
            String.localizedStringWithFormat(NSLocalizedString("email", tableName: "my-ditto-project", bundle: Ditto.getBundle(localeOverride), comment: ""))
        }

        /// [Open text item in Ditto](http://app.dittowords.com/projects-beta/<project-id>?viewState=text&selectedTextItemIds=<text-item-id>)
        ///
        /// - Returns: The localized string for the Ditto identifier "submit"
        public static func submit(_ localeOverride: String? = nil) -> String {
            String.localizedStringWithFormat(NSLocalizedString("submit", tableName: "my-ditto-project", bundle: Ditto.getBundle(localeOverride), comment: ""))
        }
    }
}
```
