Skip to content

Instantly share code, notes, and snippets.

@bauhouse
Last active September 14, 2020 22:23
Show Gist options
  • Select an option

  • Save bauhouse/ad2c0996c4bdb217f8b1d255ab7bdaca to your computer and use it in GitHub Desktop.

Select an option

Save bauhouse/ad2c0996c4bdb217f8b1d255ab7bdaca to your computer and use it in GitHub Desktop.

Revisions

  1. bauhouse revised this gist Jun 9, 2017. 1 changed file with 18 additions and 17 deletions.
    35 changes: 18 additions & 17 deletions dato.config.js
    Original file line number Diff line number Diff line change
    @@ -46,10 +46,11 @@
    ### Functions
    - setCssProperties(file, properties)
    - createIndexFile(file, data)
    - numberWithCommas(num)
    - handleize(str, sep)
    - isEmpty(obj)
    - createIndexFile(file, data)
    */
    // ============================================================
    @@ -532,6 +533,10 @@ module.exports = (dato, root, i18n) => {
    }
    };

    // ------------------------------------------------------------
    // Functions
    // ------------------------------------------------------------

    function setCssProperties(file, properties) {
    // The file to modify or set the default file
    var file = file || css_file;
    @@ -568,9 +573,18 @@ function setCssProperties(file, properties) {
    });
    }

    // ------------------------------------------------------------
    // Functions
    // ------------------------------------------------------------
    function createIndexFile(file, data) {
    // console.log("* Testing file: " + file);
    // console.log("* Testing data:" + data);
    fs.writeFile(file, data, { flag: 'wx' }, function (err) {
    if (err) {
    console.log("* Ignored " + file)
    }
    else {
    console.log("* Written " + file);
    }
    });
    }

    // https://stackoverflow.com/questions/2901102/how-to-print-a-number-with-commas-as-thousands-separators-in-javascript
    function numberWithCommas(num) {
    @@ -605,16 +619,3 @@ function isEmpty(obj) {
    }
    return JSON.stringify(obj) === JSON.stringify({});
    }

    function createIndexFile(file, data) {
    // console.log("* Testing file: " + file);
    // console.log("* Testing data:" + data);
    fs.writeFile(file, data, { flag: 'wx' }, function (err) {
    if (err) {
    console.log("* Ignored " + file)
    }
    else {
    console.log("* Written " + file);
    }
    });
    }
  2. bauhouse revised this gist Jun 9, 2017. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions dato.config.js
    Original file line number Diff line number Diff line change
    @@ -49,6 +49,7 @@
    - numberWithCommas(num)
    - handleize(str, sep)
    - isEmpty(obj)
    - createIndexFile(file, data)
    */
    // ============================================================
  3. bauhouse revised this gist Jun 9, 2017. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion dato.config.js
    Original file line number Diff line number Diff line change
    @@ -17,7 +17,7 @@
    ### Constants and Variables
    - Switches for file generation
    - Template language
    - Initialize index pages
    - Site
    - Page Defaults
    - CSS Defaults
  4. bauhouse created this gist Jun 9, 2017.
    619 changes: 619 additions & 0 deletions dato.config.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,619 @@
    // ============================================================
    // dato.config.js
    // ============================================================
    // Configuration file for DatoCMS
    // For static site generation with Harp
    // ------------------------------------------------------------
    // https://www.datocms.com/
    // https://harpjs.com/
    // ------------------------------------------------------------
    /*
    ### Packages
    - fs
    - dateFormat
    ### Constants and Variables
    - Switches for file generation
    - Template language
    - Site
    - Page Defaults
    - CSS Defaults
    - Assets CDN
    ### Data Models
    - Organization
    - Brand
    - Social Media
    - Metrics
    - Donate
    - Subscribe
    - Pages
    - Sections
    - Events
    - Races
    - Images
    ### Output Data
    - Global Variables
    - Models
    - Markdown Files
    - CSS
    ### Functions
    - numberWithCommas(num)
    - handleize(str, sep)
    - isEmpty(obj)
    */
    // ============================================================


    // ------------------------------------------------------------
    // Packages
    // ------------------------------------------------------------
    var fs = require('fs');
    var dateFormat = require('dateformat');


    // ------------------------------------------------------------
    // Constants and Variables
    // ------------------------------------------------------------

    // Switches for file generation
    // ------------------------------------------------------------
    var generate_global_variables = true;
    var generate_page_data_files = true;
    var generate_data_model_files = false;
    var generate_markdown_files = false;
    var generate_css_files = false;
    var reset_css = false;

    // Initialize index pages
    // ------------------------------------------------------------
    // Generate index pages if generate_page_data_files = true
    // (existing files will be ignored)
    var create_index_pages = false;
    var template_file_extension = 'jade';
    var default_index_content = '!= partial(\'../_shared/layout/page-title\')';

    // Site
    // ------------------------------------------------------------
    const FIRM = 'Firm Inc';
    const AUTHOR = 'Full Name';
    const SITE = 'Site Name';
    const URI = 'https://example.com';
    var description = 'Site Description';
    var version = 1.0;
    var year = new Date().getFullYear();

    // Page Defaults
    // ------------------------------------------------------------
    var title = 'Hello, world';
    var gmap = false;
    var header_style = 'dark';

    // CSS Defaults
    // ------------------------------------------------------------
    var css_file = 'public/assets/css/colors.scss';
    var css_properties = {
    '$primary-color': '#13c0d7',
    '$secondary-color': '#8dc63f',
    '$tertiary-color': '#f0bc00'
    };

    // Assets CDN
    // ------------------------------------------------------------
    var media_url = 'https://www.datocms-assets.com';


    // ------------------------------------------------------------
    // Data Models
    // ------------------------------------------------------------
    module.exports = (dato, root, i18n) => {

    // Organization
    // ------------------------------------------------------------
    var org = {
    name: dato.org.name,
    legal_name: dato.org.legalName,
    charity_name: dato.org.charityName,
    tax_number: dato.org.taxNumber,
    email: dato.org.email,
    phone: dato.org.phone,
    address: dato.org.address,
    city: dato.org.city,
    province: dato.org.province,
    postal_code: dato.org.postalCode,
    country: dato.org.country,
    google_map_url: dato.org.googleMapUrl,
    full_address: full_address
    }
    var full_address =
    dato.org.address + ', ' +
    dato.org.city + ', ' +
    dato.org.province + ', ' +
    dato.org.postalCode;

    // Brand
    // ------------------------------------------------------------
    var brand = {
    messaging: dato.brand.messaging,
    tagline: dato.brand.tagline,
    logo: dato.brand.logo.value,
    logo_dark: dato.brand.logoDark.value,
    logo_header: dato.brand.headerLogo.value,
    logo_header_dark: dato.brand.headerLogoDark.value
    }

    // Social Media
    // ------------------------------------------------------------
    var social = {};
    dato.socials.forEach(item => {
    var social_slug = item.title.toLowerCase();
    social[social_slug] = {
    title: item.title,
    slug: social_slug,
    url: item.url
    }
    });

    // Metrics
    // ------------------------------------------------------------
    var metrics = {};
    dato.metrics.forEach(metric => {
    var metric_slug = handleize(metric.title);
    metrics[metric_slug] = {
    title: metric.title,
    number: metric.number,
    value: numberWithCommas(metric.number),
    currency: metric.currency ? '$' : ''
    }
    });

    // Donate
    // ------------------------------------------------------------
    var donate = {
    projects_campaign_title: dato.donation.projectsCampaignTitle,
    projects_campaign_id: dato.donation.projectsCampaignId,
    team_donate_id: dato.donation.teamDonateId,
    operations_campaign_id: dato.donation.operationsCampaignId,
    };

    // Subscribe
    // ------------------------------------------------------------
    var subscribe = {
    title: dato.subscribe.title,
    heading: dato.subscribe.heading,
    description: dato.subscribe.description,
    message_subject: dato.subscribe.messageSubject,
    button_text: dato.subscribe.buttonText,
    form_action: dato.subscribe.formAction
    };

    // Pages
    // ------------------------------------------------------------
    var pages = {};
    dato.pages.forEach((page, index) => {
    var title_bg_img = null;
    var image = null;
    if (page.titleBgImg) {
    title_bg_img = dato.find(page.titleBgImg.id);
    image = {};
    var image_values = title_bg_img.image.value;
    image.id = page.titleBgImg.id;
    image.name = title_bg_img.name;
    image.caption = title_bg_img.caption;
    image.description = title_bg_img.description;
    for (var i in image_values) image[i] = image_values[i];
    image.url = media_url + image_values.path;
    title_bg_img = image.url;
    }
    var page_slug = page.slug;
    var parent_page = null;
    var parent_page_id = null;
    var path = '/' + page.slug;
    if (page.slug === 'index') {
    path = '/';
    }
    var parent_page_slug = null;
    if (page.parentPage) {
    parent_page = dato.find(page.parentPage.id);
    parent_page_id = page.parentPage.id;
    parent_page_slug = parent_page.slug;
    var parent_page_path = parent_page_slug;
    page_slug = parent_page_path ? parent_page.slug + '_' + page.slug : page.slug;
    path = parent_page_path ? '/' + parent_page.slug + '/' + page.slug : '/' + page.slug;
    }
    // Find child pages
    var subpages = {};
    dato.pages.forEach((subpage, index) => {
    var subpage_parent_page = null;
    var subpage_slug = null;
    if (subpage.parentPage) {
    subpage_parent_page = dato.find(subpage.parentPage.id);
    subpage_slug = subpage.slug;
    if (subpage_parent_page.slug === page.slug) {
    var subpage_path = '/' + page.slug + '/' + subpage_slug;
    subpages[subpage_slug] = {
    title: subpage.title,
    slug: subpage.slug,
    path: subpage_path
    }
    }
    }
    });
    if (isEmpty(subpages)) {
    subpages = null;
    }
    pages[page_slug] = {
    title: page.title,
    parent_page: parent_page_slug,
    slug: page.slug,
    path: path,
    heading: page.heading,
    description: page.description,
    title_bg_img: title_bg_img,
    main_menu: page.mainMenu,
    footer_menu: page.footerMenu,
    header_style: page.headerStyle ? handleize(page.headerStyle) : null,
    subpages: subpages
    }
    });

    // Sections
    // ------------------------------------------------------------
    var sections = {};
    dato.sections.forEach(section => {
    var section_slug = section.slug
    var slug = section_slug.replace(/-/g, '_')
    // ...find image by id
    var section_image = null;
    var section_image_id = null;
    var image = null;
    if (section.image) {
    section_image = dato.find(section.image.id);
    image = {};
    var image_values = section_image.image.value;
    image['id'] = section.image.id;
    image['name'] = section_image.name;
    image['caption'] = section_image.caption;
    image['description'] = section_image.description;
    for (var i in image_values) image[i] = image_values[i];
    image['url'] = media_url + image_values.path;
    }
    var background_image = null;
    if (section.backgroundImage) {
    background_image = section.backgroundImage.value;
    background_image['url'] = media_url + background_image.path;
    }
    sections[slug] = {
    title: section.title,
    slug: section.slug,
    heading: section.heading,
    lead: section.lead,
    content: section.content,
    button_text: section.buttonText,
    button_url: section.buttonUrl,
    type: section.sectionType,
    image: image,
    background_image: background_image,
    video_url: section.videoUrl
    }
    });

    // Events
    // ------------------------------------------------------------

    // Events by Year
    var events = {};
    dato.events.forEach(event => {
    var year = event.year;
    var event_slug = 'year_' + event.year;
    events[event_slug] = {};
    });

    // Events by City
    dato.events.forEach(event => {
    var city_slug = event.city.toLowerCase();
    var event_slug = 'year_' + event.year;
    var datetime = event.date;
    var date = datetime.toISOString().substring(0,10);
    var event_date = new Date(date);
    events[event_slug][city_slug] = {
    title: event.title,
    description: event.description,
    datetime_iso: event.datetime,
    date_iso: date,
    date: dateFormat(event_date, 'dddd, mmmm d, yyyy'),
    weekday: dateFormat(event_date, 'dddd'),
    day: dateFormat(event_date, 'd'),
    month: dateFormat(event_date, 'mmmm'),
    year: dateFormat(event_date, 'yyyy'),
    city: event.city,
    registration_url: event.registrationUrl
    }

    // Races by Event
    events[event_slug][city_slug]['races'] = {};
    dato.races.forEach(race => {
    if (race.event.id == event.id) {
    var datetime = race.start;
    var date = datetime.toISOString().substring(0,10);
    var race_start = new Date(datetime);
    events[event_slug][city_slug]['races']['race_' + race.slug] = {
    title: race.title,
    name: race.name,
    slug: race.slug,
    datetime_iso: datetime,
    date_iso: date,
    start: dateFormat(race_start, 'h:MMtt'),
    date: dateFormat(race_start, 'dddd, mmmm d, yyyy'),
    weekday: dateFormat(race_start, 'dddd'),
    day: dateFormat(race_start, 'd'),
    month: dateFormat(race_start, 'mmmm'),
    year: dateFormat(race_start, 'yyyy'),
    results_url: race.resultsUrl
    }
    }
    });

    });

    // Images
    // ------------------------------------------------------------
    var images = {};
    dato.images.forEach((item, index) => {
    var image_slug = 'id_' + item.id;
    images[image_slug] = {
    id: item.id,
    title: item.title,
    name: item.name,
    file: item.file,
    caption: item.caption,
    description: item.description,
    image: item.image.value
    }
    images[image_slug].image.url = media_url + images[image_slug].image.path;
    });

    // Globals
    // ------------------------------------------------------------
    var globals = {
    globals: {
    firm: FIRM,
    author: AUTHOR,
    site: SITE,
    uri: URI,
    description: description,
    version: version,
    site_name: dato.org.name,
    status: dato.brand.status,
    media_url: media_url,
    year: year,
    title: title,
    gmap: gmap,
    header_style: header_style,
    org: org,
    brand: brand,
    social: social,
    metrics: metrics,
    donate: donate,
    subscribe: subscribe,
    pages: pages,
    sections: sections,
    events: events
    }
    };

    // ------------------------------------------------------------
    // Output Data
    // ------------------------------------------------------------

    // Global Variables
    // ------------------------------------------------------------
    if (generate_global_variables) {
    root.createDataFile('harp.json', 'json', globals);
    }

    // Pages
    // ------------------------------------------------------------
    if (generate_page_data_files) {
    var page = null;
    var path = 'public/';
    var data_filename = '_data.json';
    var data_file = path + data_filename;
    var index_filename = 'index.' + template_file_extension;
    var index_file = path + index_filename;

    for (key in pages) {
    page = pages[key];
    if (key != 'index') {
    path = 'public' + page.path + '/';
    }
    root.createDataFile(path + data_filename, 'json', { index: page });

    if (create_index_pages) {
    index_file = path + index_filename;
    createIndexFile(index_file, default_index_content)
    }
    }
    }

    // Models
    // ------------------------------------------------------------
    if (generate_data_model_files) {
    root.createDataFile('public/_data/org.json', 'json', org);
    root.createDataFile('public/_data/brand.json', 'json', brand);
    root.createDataFile('public/_data/social.json', 'json', social);
    root.createDataFile('public/_data/metrics.json', 'json', metrics);
    root.createDataFile('public/_data/donate.json', 'json', donate);
    root.createDataFile('public/_data/subscribe.json', 'json', subscribe);
    root.createDataFile('public/_data/pages.json', 'json', pages);
    root.createDataFile('public/_data/sections.json', 'json', sections);
    root.createDataFile('public/_data/events.json', 'json', events);
    root.createDataFile('public/_data/images.json', 'json', images);
    }

    // Markdown Files
    // ------------------------------------------------------------
    if (generate_markdown_files) {
    // Create a `public/_sections` directory (or empty it if already exists)
    root.directory('public/_content/sections', dir => {
    // For each Section
    dato.sections.forEach((section, index) => {

    var background_image = null;
    if (section.backgroundImage) {
    background_image = section.backgroundImage.value;
    }

    // Create a markdown file with all the metadata in the frontmatter
    if (section.content) {
    dir.createPost(`${section.slug}.md`, 'yaml', {
    frontmatter: {
    title: section.title,
    slug: section.slug,
    heading: section.heading,
    lead: section.lead,
    content: section.content,
    button_text: section.buttonText,
    button_url: section.buttonUrl,
    type: section.sectionType,
    background_image: background_image,
    video_url: section.videoUrl
    },
    content: section.content
    });
    }

    // Create a markdown file with only the content field
    if (section.content) {
    dir.createPost(`${section.slug}-content.md`, 'md', {
    content: section.content
    });
    }

    // Create a markdown file with only the lead field
    if (section.lead) {
    dir.createPost(`${section.slug}-lead.md`, 'md', {
    content: section.lead
    });
    }

    });
    });
    }

    // CSS
    // ------------------------------------------------------------
    // Modify SCSS properties in public/assets/css/colors.scss

    // The file to modify
    var file = 'public/assets/css/colors.scss';
    // Find properties and assign new values
    var properties = null;
    if (reset_css === false) {
    properties = {
    '$primary-color': dato.brand.primaryColor,
    '$secondary-color': dato.brand.secondaryColor,
    '$tertiary-color': dato.brand.tertiaryColor
    };
    }
    // Write the changes to the file (omit properties to reset to default)
    if (generate_css_files) {
    setCssProperties(file, properties);
    }
    };

    function setCssProperties(file, properties) {
    // The file to modify or set the default file
    var file = file || css_file;
    // Find properties and assign new values or provide defaults
    var properties = properties || css_properties;

    // Read file
    fs.readFile(file, 'utf8', function (err,data) {
    if (err) return console.log(err);

    // Replace properties with regular expressions
    var pattern = '';
    var value = '';
    var replace_str = '';

    // Perform replacements on result
    var result = data;

    for (property in properties) {
    // Build replacement strings for each property
    pattern = '(\\' + property + ':)(.+?);';
    value = properties[property];
    replace_str = property + ': ' + value + ';'
    // Replace the matching properties in the file
    result = result.replace(RegExp(pattern, 'g'), replace_str);
    }

    // Write file
    fs.writeFile(file, result, 'utf8', function (err) {
    if (err) return console.log(err);
    });
    // Log change to console
    console.log("\n* Written " + file);
    });
    }

    // ------------------------------------------------------------
    // Functions
    // ------------------------------------------------------------

    // https://stackoverflow.com/questions/2901102/how-to-print-a-number-with-commas-as-thousands-separators-in-javascript
    function numberWithCommas(num) {
    var parts = num.toString().split(".");
    parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    return parts.join(".");
    }

    // https://gist.github.com/tyteen4a03/3420a9e121d13b091343
    function handleize(str, sep) {
    sep = sep || '_';
    str = str.toLowerCase();
    var toReplace = ['"', "'", "\\", "(", ")", "[", "]"];
    for (var i = 0; i < toReplace.length; ++i) {
    str = str.replace(toReplace[i], "");
    }
    str = str.replace(/\W+/g, sep);
    if (str.charAt(str.length - 1) == sep) {
    str = str.replace(/-+\z/, "");
    }
    if (str.charAt(0) == sep) {
    str = str.replace(/\A-+/, "");
    }
    return str
    }

    // https://stackoverflow.com/questions/679915/how-do-i-test-for-an-empty-javascript-object
    function isEmpty(obj) {
    for(var prop in obj) {
    if(obj.hasOwnProperty(prop))
    return false;
    }
    return JSON.stringify(obj) === JSON.stringify({});
    }

    function createIndexFile(file, data) {
    // console.log("* Testing file: " + file);
    // console.log("* Testing data:" + data);
    fs.writeFile(file, data, { flag: 'wx' }, function (err) {
    if (err) {
    console.log("* Ignored " + file)
    }
    else {
    console.log("* Written " + file);
    }
    });
    }