Skip to content

ContentStep

javarome edited this page May 21, 2024 · 6 revisions

A ContentStep is parameterized by its ContentStepConfigs. Each of these configs specifies how the ContentStep will:

  1. for each of its specified contentsConfig.
    1. processRoots(contents.roots)
      1. processRoot(root)
        1. processFile(file)
  2. execute its Replacements on each of them, until the file doesn't change anymore.
  3. saves the modified file contents in according to its outputSpec.

Configurations

A ContentStep processes a set of configurations, which defines:

  • which files have to be processed
  • which replacements have to be executed on the contents of those files
  • what is will be the output file for each input file

For instance, the ContentStepConfig configuration below is about writing a netlify.toml file which as generated from the contents of an .htaccess file:

const contentStepConfig: ContentStepConfig = {    
  roots: [".htaccess"],
  replacements: [
    new HtAccessToNetlifyConfigReplaceCommand("https://rr0.org/")
  ],
  getOutputPath(context: SsgContext): string {
    return "out/netlify.toml"
  }
}

The example below processes 2 content configs:

  • one that converts a .htaccess file to a netlify.toml file ;
  • one that replace HTML and Ssg tags of files from large number of directories, with a series of replacements. In that case the output file name is not changed.
const contentConfigs: ContentStepConfig[] = [
  {
    roots: [".htaccess"],
    replacements: [new HtAccessToNetlifyConfigReplaceCommand("https://rr0.org/")],
    getOutputPath(context: SsgContext): string {
      return "out/netlify.toml"
    }
  },
  {
    roots: [
      "index.html", "404.html", "googlebe03dcf00678bb7c.html", "Contact.html", "Copyright.html", "preambule.html", "FAQ.html", "Referencement.html",
      "croyance/**/*.html",
      "droit/**/*.html",
      "org/**/*.html",
      "people/**/*.html",
      "place/**/*.html",
      "politique/**/*.html",
      "science/**/*.html",
      "tech/**/*.html",
      "time/**/*.html",
      "politique/**/*.html",
      "udb/*.html",
      "js/**/*.html"
    ],
    replacements: [
      /**
       * Replaces `<!-- #include virtual="myFileName" -->` by myFileName's contents.
       */
      new SsiIncludeReplaceCommand(),
      /**
       * Inserts translation links if language variant files are found.
       */
      new LanguageReplaceCommand(),
      /**
       * Inserts <h1>title</h1> title from <title>title</title> tag.
       */
      new TitleReplaceCommand([timeDefaultHandler]),
      /**
       * Replaces ${mail} by context.getVar("mail") value.
       */
      new StringEchoVarReplaceCommand("mail"),
      /**
       * Replaces ${mapsApiKey} by context.getVar("mapsApiKey") from process.env.
       */
      new StringEchoVarReplaceCommand("mapsApiKey"),
      /**
       * Replaces {{var}} by context.getVar("var").
       */
      new AngularExpressionReplaceCommand(),
      new SsiEchoVarReplaceCommand("copyright", [rr0DefaultCopyright]),
      new SsiIfReplaceCommand(),
      new SsiSetVarReplaceCommand("title", (match: string, ...args: any[]) => `<title>${args[0]}</title>`),
      new SsiSetVarReplaceCommand("url",
        (match: string, ...args: any[]) => `<meta name="url" content="${args[0]}"/>`),
      new SsiLastModifiedReplaceCommand(context.time.options),
      new AuthorReplaceCommand(),
      /**
       * Replaces <time>YYYY-MM-DD</time> tags.
       */
      new HtmlTagReplaceCommand("time", new TimeReplacerFactory(timeFiles)),
      /**
       * Replaces <span class="people">People name</span> tags.
       */
      new ClassRegexReplaceCommand("people", new PeopleReplacerFactory()),
      new ClassDomReplaceCommand("place", new PlaceReplacerFactory(placeService, orgService)),
      new ClassRegexReplaceCommand("temoin(.?)", new WitnessReplacerFactory()),
      new ClassDomReplaceCommand("note", new NoteReplacerFactory()),
      new ClassDomReplaceCommand("source", new SourceReplacerFactory()),
      new LinkReplaceCommand(new TimeLinkDefaultHandler(timeFiles)),
      new OutlineReplaceCommand(),
      new AnchorReplaceCommand("https://rr0.org/")
    ],
    getOutputPath(context: SsgContext): string {
      return "out/" + context.file.name
    }
  }
]
const contentStep = new RR0ContentStep(contentConfigs, outputFunc)

Custom ContentStep

The ContentStep class can be specialized to refine the processXxx() behaviors.

The example below resets a part of its custom Context RR0SsgContext before processing each file:

export class RR0ContentStep extends ContentStep {

  protected processFile(context: RR0SsgContext, filePath: string, contentsConfig: ContentStepConfig,
                        contentCount: number): Promise<number> {
    context.time.reset()  // Don't use time context from previous page.
    return super.processFile(context, filePath, contentsConfig, contentCount);
  }
}
Clone this wiki locally