1.2.2 • Published 3 years ago

@salespreso/slide-tools v1.2.2

Weekly downloads
-
License
ISC
Repository
-
Last release
3 years ago

SLIDE TOOLS

Installation

When using slide-tools as a part of your content development workflow.

  • check out your chosen LivePreso deck
  • run yarn add -D @salespreso/slide-tools

Development

When upgrading and adding new features to the slide-tools project.

  • check out the project to a location of your choice
  • run yarn
  • run yarn link
  • open the LivePreso deck directory you wish to test against
  • run yarn link "@salespreso/slide-tools"

Contents



add_slide and add_section

These commands use inquirer.js to build a series of questions to be answered by the user in order to create a section or slide.

Some questions, such as slide or section ID, where within a section a slide should be inserted, are always asked. The user inputs are assembled in an object. For a new slide they look like this:

{ sectionId: 'property_journey_rent',
  insertIndex: 2,
  slideId: 'dave',
  slideTitle: 'Dave',
  template: 'columns'
}

Because inquirer.js takes a plain JS object as the configuration for its series of prompts / questions, a given template can request template-specific questions by defining a JSON file (parameters.json) in its template root. This can then generate an extended, template-specific series of values for the the template to utilise.

For instance, the columns template needs to know the column setup for the slide (how many columns, the width of each etc). When the addslide command is added, and a columns template selected, a second data object is created.

{ classes: ['collapsed', 'animated'],
  height: 'column-group--height-half',
  columns:
   [
     { width: '1', uid: 'frank', bg_colour: '' },
     { width: '2', uid: 'charlie', bg_colour: 'l-grey-50' }
   ]
}

templates

Templates are done using lodash / underscores tags. When the template is supplied with specific vars, the slideId & slideTitle from the global options are included, to do fundamentals like the scss selector for the slide.

In order to cleanly guard against undefined variables in the template's variable scope (which can cause exceptions), all vars are scoped under a 'data' variable. So a simple template tag looks like this:

<%= data.slideTitle %>

In the columns template case, the template contains a loop to generate columns. It also has a need to know the total number of columns, in order to define which class to apply to the grid as a whole, for column widths. Instead of asking up front, for this value, it can be calculated within the template, using plain JS:

<% columnTotal=0;
   for (var i = 0; i < data.columns.length; ++i) {
    columnTotal+=parseInt(data.columns[i].width);
   }
%>

configuration and prompt types

Inquirer.js ships with a number of predefined prompt types. I've added 3 third-party extensions to those on offer. One of these (inquirer-select-line) is used in the core configuration, to determine where a slide is inserted in the section's slide sequence. The others are loaded only so that they can be utilised by individual templates. If there is a specific need for additional 3rd party prompts, we can add a require() statement for it in the script, to make it available.

usage

these instructions may change depending on how the tools are ultimately packaged The tools shoud be run from the project root. If the project.yaml is not found in the cwd, the script will exit.

node ./slide_tools/slide_tools.js [command]

Where command is one of addsection or add_slide.

The addsection command exposes the entered section ID and section title as slideId and slideTitle to the template. This allows slide & section templates to be used interchangeably (unsure if there is value in this). percent

under the hood

Various checks are currently performed.

  • if the section ID to be created already exists, the script will exit
  • if a given slide ID already exists (or a folder with that ID exists), the script will exit
  • there is currently no check for global uniqueness for slide IDs (as required by imposter); this could easily be added.

Once the checks pass

  • the template directory is copied to its destination
  • the parameters.json removed, if it exists
  • the files found (index.html or index.njk, slide.scss) there are loaded, the templates run, and the result is written back to the same file.

add_editable_ids

This command uses shortid.js to add unique keys to HTML elements tagged with the data-companywide-editable and data-companywide-editable-image tags. The script looks for article tags in each index.html to determine the slide's id, and creates keys with the form:

data-companywide-...="[slide_id]_editable_[shortid]"

The keys will only be added to the companywide attribute if there isn't one already, so you can run this multiple times on the same project and it won't clobber your old keys.


export_deck command

Run from the project root, it can be used to create a child deck from the current one, in a unique dir, ready for upload.

Takes the following switches

  • -d <targetdir> destination dir for the place you are exporting tool
  • -y <child.yaml> a unqiue yaml file for this deck

The child.yaml only needs 2 keys - key and sections. The child.yaml is merged with the project.yaml using _.default(), so the potential exists to have other child-unique keys, such as hooks.

When run, the script reads the project.yaml and child.yaml, creates the target directory, copies the dist directory and creates a new merged project.yaml inside it (as well as an empty src directory).

The resulting output directory can then be loaded into the CDK and uploaded, under its own unique key.

Examples:

slide_tools export_deck -d ../product-showcase -y product-showcase.yaml

This example creates/replaces a directory one level back call "product-showcase" based on the child project yaml requirements specified in "product-showcase.yaml".

Migrating slides

If a slide exists in the child.yaml but is not found in the corresponding section of the source yaml, then it will searched for by key, and migrated from elsewhere in the source deck, if found. If it is not found, the script will exit.

If a section exists in the target deck, but not the source, an error will be thrown (as the resulting section will be missing a title slide).

templates

A child yaml's sections and slides can specify if they wish to use a slide from the parent.yaml as a template. This is done by adding meta_template to the desired section/slide with a path of section_key/slide_key to declare which section/slide you wish to use as the template. Templated slides in the child.yaml will then be built out by copying over the specified templates.

slides

If no slides are declared for a section using a template, the template section's slides will be copied over to along with the rest of the section's files. If slides are specified for a section using a template, these will be used instead of the template section's slides. In order to omit slides from a section using a template, you will need to declare an empty array.

tags

Similar to a section's slides, if no tags are specified for a child.yaml section/slide using a template, they will receive the template's tags. If tags are declared, none of the template section/slide's tags will be copied over. If you do not wish for any tags to be applied to the resulting section/slide, you must declare an empty array.

variables

Any occurances of the template section/slide's key or title in the index.html, slide.css, slide.js or svgs of the desintation slide will be replaced by the key and title of the section/slide as declared in the child.yaml.

If the template section's slides are in use, the section's key and title will also flow through to the generated slides. Both the section key/title and slide key/title can be declared in a template section's slides, and will be replaced accordingly in these use-cases.

Additional vars can be specified using meta_template.vars.

Example

parent.yaml

...
sections:
   -
      key: introduction
      title: Introduction
      slides:
         - { key: standard_slide, title: Standard slide }
   -
      key: template_divider_section
      title: Section (template)
      slides:
         - { key: template_performance_slide, title: Performance Slide (template) }
         - { key: template_stats_slide, title: Stats Slide (template) }

child.yaml

...
sections:
   -
      key: introduction
      title: Introduction
      slides:
         - { key: standard_slide, title: Standard slide }
   -
      key: malvern_office
      title: Malvern Office
      meta_template:
         path: template_divider_section
      # No slides have been specified, slides will be generated
      # using slides included in the template section
   -
      key: kew_office
      title: Kew Office
      meta_template:
         path: template_divider_section
      slides:
         -
            key: kew_performance
            title: Kew Performance
            meta_template:
               path: template_performance_slide
         # Slides have been specified, this will be used instead of the
         # section template's slides
   -
      key: prahran_office
      title: Prahran Office
      meta_template:
         path: template_divider_section
      slides: []
         # No slides will be included in this section
   -
      key: malvern_office
      key: malvern_office
      title: Malvern Office
      meta_template:
         path: template_divider_section
         vars:
            occupants: 10
            cost: 150
            # Any occurances of these var keys in the template_divider_section
            # will be replaced with these values when the child deck is built out

Example:

child.yaml

...
sections:
   -
      key: malvern_office
      key: malvern_office
      title: Malvern Office
      meta_template:
         path: template_divider_section
         vars:
            occupants: 10
            cost: 150
            # Any occurances of these var keys in the template_divider_section
            # will be replaced with these values when the child deck is built out

import_state command

allow you to inject a full set of feeds and a context into the CDK application, based on either a onlinepreso invite link, or a file generated within the App itself.

usage

from a url

slide_tools import_state --title="New Test Feed Name" --url=<your preso url> - import from a preso URL. IN this case the URL is parsed and /bundle is added to put the configuration of the presentation.

from a file

slide_tools import_state --title="New Test Feed Name" --file=<file path> - import from a file exported from the app. The format of a file for import is a simple json object with context and feeds top level keys. A sample export script, that can be pasted into the console of the App, is as follows;

var extractDataTo = function(fileName) {
    var comboBlob = { feeds: Bridge.Feed.feeds, context: Bridge.Context.getDict()};
    var fs = nw.require("fs");
    var path = nw.require("path");
    var os = nw.require("os");
    var outputFile = path.resolve(os.homedir(), fileName);
    fs.writeFileSync(outputFile, JSON.stringify(comboBlob, null, 2));
};

Calling the above with extractDataTo("output.json"); will create output.json in the root of the user's home directory.

import_state will not overwrite the existing feeds.json and context.json files in your project's data directory, unless you explicitly use the --execute switch. Without it, the script will generate a pair of new JSON files taht you can compare to the originals, and then replace if you are happy. This behaviour is a safeguard while any bugs are worked out. When --execute is specified, a feeds.json.bak will be saved to allow rollback to the previous state.


earlier notes

On next running gulp, you may see a nunjucks error, but it's not in the generated output, I think nunjucks is trying to compile the raw templates (with underscores tags in them). The selector for *.njk files needs to be tightened to only include those in src

Copying the slide_tools and templates folder across to a fresh project, and then creating / editing templates to suit, will allow the code to be recycled; ultimately, it should be wound in to the gulp tasks, as there's nothing here that's project specific. Would just need a few more checks / warnings to make sure the template directories existed.