Skip to content
This repository has been archived by the owner on Apr 26, 2019. It is now read-only.

The structure of the website

Mari Johannessen edited this page Jul 10, 2018 · 9 revisions

Introduction

carbondesignsystem.com is created with React and is using a combination of tools and packages in order to render its content. This page explains how the website is set up and how to update certain parts of the website.

Before getting started, make sure you have a local version of the website and that you are working from a fork and a branch.

Overall structure

The main structure of the website is the following:

build
config
├── env.js
├── paths.js
├── polyfills.js
├── webpack.config.dev.js
├── webpack.config.prod.js
public
scripts
├── build.js
├── crawler.js
├── frontmatter.js
├── start.js
src
├── app
│   └── components
│       └── custom
│       └── internal
│   └── pages
│       └── add-ons
│       └── component-status
│       └── components
│       └── data-vis
│       └── getting-started
│       └── guidelines
│       └── overview
│       └── resources
│       └── style
│       └── themes
│       └── whats-new
│       ├── 404.js
│   └── scss
│       └── global
│       ├── main.scss
├──assets
│   └── downloads
│   └── fonts
│   └── images
│   └── syntax
├── content
│   └── add-ons
│   └── components
│   └── getting-started
│   └── guidelines
│   └── overview
│   └── resources
│   └── style
│   └── themes
│   └── whats-new
│   ├── main.scss
├── data
│   └── add-ons
│   └── components
│   └── guidelines
│   ├── colors.json
│   ├── component-status.json
│   ├── data-vis-colors.json
│   ├── site-nav-structure.json
│   ├── sitecontent.js
├── polyfills
│   ├── custom-event.js
│   ├── element-closest.js
│   ├── element-matches.js
│   ├── index.js
│   ├── toggle-class.js
├── carbon-components.js
├── index.js
├── routes.js
index.js
manifest.yml

The build folder

The build folder is auto-generated when running the commands npm run build-external or npm run build-internal. We run these commands before deploying the website to IBM Cloud both for our public site (http://www.carbondesignsystem.com) and our internal site (http://design-system.stage1.mybluemix.net/). It is used by express in the root index.js file to serve our static files such as images, CSS files, and JavaScript files. The CSS and JavaScript files are generated using webpack while the HTML is being generated from the index.hbs file in the public folder.

app.use(express.static('./build'));

app.get('/*', (req, res) => {
  res.setHeader('Content-Type', 'text/html; charset=UTF-8');
  res.sendFile(path.join(__dirname, './build', 'index.html'));
});

The config folder

The config folder includes the files needed for the webpack configuration and the files are all based directly off of the files used in create-react-app.

env.js defines the environment variables used in the webpack config. paths.js includes shorthands for all the different paths used in the webpack config. polyfills.js includes some of the polyfills needed for React.

webpack.config.dev.js is the Webpack configuration file for the dev setup. It takes care of parsing our React application and making sure a static website is bundled up and generated with all of our needed assets. webpack.config.prod.js is the Webpack configuration file for the production setup. The biggest difference between the dev config and the prod config is that the prod config includes parts for uglifying our HTML and JS.

The scripts folder

The scripts folder includes some of the scripts we use on the website to automate certain tasks and to generate content.

The build.js file generates our build folder and is triggered using the commands npm run build-external and npm run build-internal. These two commands both run this file, but with different environment variables set based on whether or not the website needs to be built for internal or external purposes.

The crawler.js file is used to build the internal search on the website. It goes thorugh each of the markdown files on the website and creates JavaScript objects for them to be consumed in the React component created for the internal search.

The frontmatter.js file is a script file that goes through the code.md file for each component. The code.md file includes information that we're using to display the code for each component on the Component pages on the website. We will explain this further later.

The start.js file is used to start the server after the website is built and is run by running the command npm run start. This is useful for doublechecking that the website is running as expected before deploying to IBM Cloud.

The src folder

The src folder is where most of the work on the website is done.

The app folder

The app folder is the main folder for all of the React components used on the website. The components folder contains the components needed to built pages on the website. They are divided into 2 categories - custom and internal.

Internal components

The internal components are used to create important parts of the website such as the page header, the page footer, the page itself, etc.

Custom components

The custom components are React components that we build into the markdown files in order to show more complex content on some of the pages without adding too much markup to the content files (which are all markdown files). To create a custom component you can do the following:

  1. Find the content markdown file for the page you want to add the custom component. For example, if you want to add a custom component to the Motion page, open the motion.md file in the content folder. Find the place in the markdown file where you want the custom component to be inserted. Then add the following line:
<div data-insert-component="NameOfCustomComponent"></div>

If you need to add any props to your custom component, then you can add it using the data-attribute data-props and pass them in the order you are going to accept them in your custom component.

<div data-insert-component="NameOfCustomComponent" data-props="prop1,prop2,prop3"></div>
  1. Create the React component in the custom folder. Example:
import React, { Component } from 'react';
import PropTypes from 'prop-types';

class NameOfCustomComponent extends Component {
  static propTypes = {
    prop1: PropTypes.string,
    prop2: PropTypes.string,
    prop3: PropTypes.string,
  }

  render() {
    const {
      prop1,
      prop2,
      prop3,
    } = this.props;

    return (
      <div>My custom component here</div>
    );
  }
}

export default NameOfCustomComponent;
  1. Import the component in Page.js, and add it to the addCustomComponent method.
// Page.js

import NameOfCustomComponent from '../../custom/NameOfCustomComponent';

...

addCustomComponent = () => {
  const customComponents = {
    ...
    NameOfCustomComponent
  };

  ...

  // If your component uses props, add an `else if` statement to the end of the method
 } else if (comp === 'Video') {
   const videoProp = component.dataset.props;
   ReactDOM.render(<NewComponent videoLink={videoProp} />, component);
 // Your code begins here
 } else if (comp === 'NameOfCustomComponent') {
   const props = component.dataset.props.split(',');
   ReactDOM.render(
     <NewComponent
      prop1={props[0]}
      prop2={props[1]}
      prop3={props[2]}  
    />,
    component
   );
 } else {
   ReactDOM.render(<NewComponent />, component);
 }
}

If the custom component needs any CSS, then you have to also import this file in src/app/scss/main.scss.

Internal vs External content

Some of the content on the website is only available on our internal staging website. We're using environment variables to differentiate between internal and external. This is used in the SideNav component (line 123-128) to make sure that the internal pages are not rendered on the external site's side nav. It is also used on the pages that are internal. Right now this is only the YourProductOnIBMCloud.js component.

To view the internal website while developing, run ENV=internal npm run dev.