Skip to content
This repository has been archived by the owner on Nov 29, 2022. It is now read-only.

Latest commit

Β 

History

History
366 lines (270 loc) Β· 14.5 KB

CONTRIBUTING.md

File metadata and controls

366 lines (270 loc) Β· 14.5 KB

Contributing to electronjs.org

πŸ‘πŸŽ‰ Thanks for taking the time to contribute! πŸŽ‰πŸ‘

The following is a set of guidelines for contributing to the Electron website on GitHub. These are just guidelines, not rules, so use your best judgment and feel free to propose changes to this document in a pull request.

Table of Contents

Issues and Pull Requests

  • If you're not sure about adding something, open an issue to discuss it.
  • Feel free to open a Pull Request early so that a discussion can be had as changes are developed.
  • Include screenshots and animated gifs of your changes whenever possible.

Commit Messages and Pull Request Titles

We use the Conventional Commits specification to standardize our commit history. To enforce this convention on commit messages and/or pull request titles, we use the Semantic Pull Requests bot.

The commit message summary (or pull request title) is constructed by prepending the type of change being made (e.g., feat, fix, refactor), followed by an imperative, present tense sentence (without a period). Example: fix: make header bold

Pull Request Title

Same as commit messages, prepend the type of change being made (refactor, fix, chore, feat, etc.) Example: docs: add linux setup instructions

Heroku Review Apps

Heroku Review Apps make it easier for reviewers to see the effects of a proposed change. Whenever a pull request is opened on the website repo, the branch is autodeployed to Heroku with a unique URL like electron-website-pr-787.herokuapp.com. You'll see a notification on GitHub after the branch has been deployed. When pull request is closed or merged, the ephemeral app is destroyed.

review app notification

Heroku Deployment

Heroku automatically deploys the master branch, so that branch should always be in a good state. Preboot is on for the site, so after a deployment there will be a period of a few minutes where old dynos are still serving traffic.

Running the Site

Follow these steps to copy this repository to your computer and build the site:

git clone https://github.com/electron/electronjs.org
cd electronjs.org
yarn install
yarn dev

You should now have an Express server running at localhost:5000 πŸŽ‰

Installation Troubleshooting

If there is an error building the node-sass dependency, try running npm rebuild node-sass.

Note: If errors are still shown after you have installed all the dependencies, try to delete the node_modules directory in your project and run yarn again.

Read on for more info about the structure of the site.

Editing Content

The content on electronjs.org comes from a number of sources.

Documentation

Electron's English API docs and tutorials live in the electron/electron repo in the docs directory. Contributions to the documentation should be made there: electron/electron.

After being translated on Crowdin, all the docs are automatically updated on the electron/electron-i18n repo and auto-published to npm as the electron-i18n package. That package is in turn used by this website repo as the source of all documentation. See electron/electron-i18n#usage for an explanation of the documentation data's structure.

Apps

The website has a page at electronjs.org/apps that features applications built on Electron. If you want to add an app to the site, see the electron-apps repo.

Blog

Blog posts have been moved to https://github.com/electron/electronjs.org-new

Localized Strings

The /data/locale.yml file contains English strings that are used throughout the site. This file is synced with Crowdin as part of the translation pipeline. These strings are displayed on the site in the visitor's target language if available, with a fallback to the English value if no translation exists yet.

To use localized strings in views, use the localized object, which is generated automatically by the context middleware:

<p>{{{localized.web_technologies.description}}}</p>

Content for page titles and other metadata like Facebook OpenGraph and Twitter Cards meta tags is also defined in the /data/locale.yml file, e.g. pages['/apps'].title and pages['/apps'].description. If a localized title and/or description are present for a given route, they will be added to the <head> of the rendered page automatically.

Translations

Electron's API documentation, tutorials, and website content are translated into other languages on a third-party site called Crowdin. Crowdin is a free and open tool, and anyone is welcome to join in the translation process. You can create an account easily and quickly by logging in with your GitHub account.

See electron/electron-i18n for info on how to get started, or jump right into translating at crowdin.com/project/electron.

Announcement Banner

The top-level banner for showing the information (for example, a new Electron version or important blog post).

To show or update the announcement banner, modify the announcement string in data/locale.yml, and update the conditional inside the showAnnouncementBanner constant in middleware/context-builder.js.

Crowdin Proxy

To allow open source community members to develop electronjs.org and electron-i18n, we've added a feature to the Electron website that allows Crowdin API requests to be made without an API key. The following routes are supported:

Electron URL Crowdin Docs
GET /crowdin/status status
GET /crowdin/language-status language-status
GET /crowdin/info info
GET /crowdin/download-glossary download-glossary
GET /crowdin/export-file export-file

Sharing Localized URLs

If you wish to share a URL linking to a translated page of the Electron website, add a lang param to the URL. This will override the visitor's existing language preferences and display the given page in the specified language:

Example: /docs/api/browser-window?lang=fr-FR

Routes

Website routes are defined in server.js.

Here's an example of a basic route:

app.get('/docs', routes.docs.index)

In the snippet above, GET requests to the /docs path on the site will be sent to the routes.docs.index function (called a route handler) that accepts the incoming request and renders the docs index page.

Route handlers live in /routes and follow a Ruby-on-Rails-inspired naming convention:

routes
β”œβ”€β”€ apps
β”‚Β Β  β”œβ”€β”€ index.js
β”‚Β Β  └── show.js
β”œβ”€β”€ community.js
β”œβ”€β”€ contact.js
β”œβ”€β”€ docs
β”‚Β Β  β”œβ”€β”€ category.js
β”‚Β Β  β”œβ”€β”€ index.js
β”‚Β Β  └── show.js
β”œβ”€β”€ home.js
β”œβ”€β”€ index.js
β”œβ”€β”€ languages
β”‚Β Β  └── index.js
β”œβ”€β”€ releases.js
└── userland
    β”œβ”€β”€ index.js
    └── show.js

Middleware

This site makes extensive use of Connect (Express) middleware. Some examples:

  • Compile Sass to CSS
  • Compile futuristic JavaScript to ES5
  • Redirect old unsupported URLs
  • Redirect to remove trailing slashes from URLs
  • Prevent XSS attacks
  • Parse Accept-Language header to choose site locale.

Some of the middleware exists as npm packages, and some is custom to our project. See /middleware for the custom stuff, and server.js for the rest.

Views

Views live in the /views directory, and are written in Handlebars.

Handlebars provides a very small set of built-in helpers like if/else, unless, each, with, and a few others for use in your templates.

We extend the default set of helpers using lobars, a package that exports lodash functions as Handlebars helpers.

The express-hbs module adds support for things like nested layouts and partials.

  • Views live in /views
  • Layouts wrap views, and can be nested. They live in /views/layouts
  • Partials are reusable templates. They live in /views/partials

Context

Every view can be passed a context, an object prepared by the server that contains data to be used in the Handlebars templates. We use a custom middleware to assemble a default context object with data that is common to every view. See middleware/context-builder.js.

The context builder middleware is executed before the views, so every route handler has a req.context object that can be modified if needed.

Here's an example of a route handler that doesn't change anything:

module.exports = (req, res) => {
  res.render('somepage', req.context)
}

Here's an example where the handlers makes some changes to the context object:

module.exports = (req, res) => {
  const context = Object.assign(req.context, {
    custom: 'stuff'
  })

  res.render('somepage', context)
}

Styles

Stylesheets are written in Sass SCSS format, and they all live in the /styles directory. The server doesn't write any compiled CSS to disk: A GET request to /styles/index.css compiles and serves up the /styles/index.scss file automatically.

The styles are based on Primer, the CSS toolkit that powers GitHub's front-end design. It's purposefully limited to common components to provide our developers with the most flexibility, and to keep GitHub uniquely GitHubby. It's built with SCSS and available via NPM.

Frontend JavaScript

Frontend code lives in the /scripts directory, (not to be confused with /script). The /scripts/index.js file requires and bundles all the other files in the directory using Babel and Browserify. This means you can write any kind of futuristic JavaScript you want, and also use node-style require statements to bring in any (browserify-compatible/bundleable) dependencies.

Most of the individual files export a module that expects to have access to the DOM, so they should be executed in a DOMContentLoaded event handler:

document.addEventListener('DOMContentLoaded', () => {
  require('./create-filter-list')()
  require('./fix-platform-labels')()
  require('./update-demo-app-download-link')()
  require('./update-app-download-links')()
  require('./apply-active-class-to-active-links')()
  require('./remove-scheme-from-link-text')()
  require('browser-date-formatter')()
})

Like the Sass middleware, no compiled JavaScript code is written to disk. When a GET request is made to /scripts/index.js, the server dynamically compiles the scripts/index.js file to browser-compatible ES5.

Google Analytics Events

We use Google Analytics Events to measure usage of features that we provide on the website.

To add an event, you need to provide data-sc-category and data-sc-name properties to an element in the DOM. If data-sc-category is not provided, general will be used as a default category for the event.

Example

<button data-sc-category="docs" data-sc-name="Docs page opening">Open docs page</button>

Scripts

This repo follows the Scripts to Rule Them All methodology popularized by GitHub. The idea is that every project, regardless of the programming languages used within it, should have a /script directory containing all the necessary executable files required to set up and use the project, like /script/bootstrap and /script/start

In keeping with Node.js and npm conventions, all the scripts in this project are also defined in the scripts stanza in the package.json file. To list all available commands, type npm run.

Environment Variables

  • NODE_ENV is set to production on the server. This has a number of effects:
    • Express caches routes in memory
    • Sass middleware serves minified CSS and caches it
    • Browserify middleware serves minified JavaScript and caches it

Need Help?

Join The Discord Server!

Join the Discord server to get connected to thousands of devs creating awesome projects with Electron

  • Get help regarding any issue you are facing.
  • Make new friends, working in the same space
  • Find amazing projects to contribute to, or help others with their issues

If any of this information confusing, incorrect, or incomplete, feel free to open an issue for help.