mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-16 18:46:57 +02:00
Adds sitemap.xml. Adds 'Help Translate' to translatable strings. Error messages and fn name cleanups. (#136)
* added a note about needing more than one language to be enabled to allow for a drop down * Removing debug statements * Add 'Help Translate' to translatable strings, improves error messages around missing translated strings, calls write-translations on some routes * Adds sitemap.xml to live server and build. Versioning not supported. -- Also did some file name and module cache cleanups.
This commit is contained in:
parent
30eea17a24
commit
bcba05ae03
19 changed files with 495 additions and 245 deletions
|
@ -75,7 +75,7 @@ headerLinks: [
|
|||
|
||||
`footerIcon` - url for a footer icon. Currently used in the `core/Footer.js` file provided as an example, but it can be removed from that file.
|
||||
|
||||
`recruitingLink` - url for the `Help Translate` tab of language selection when languages besides English are enabled. This can be included you are using translations but does not have to be.
|
||||
`translationRecruitingLink` - url for the `Help Translate` tab of language selection when languages besides English are enabled. This can be included you are using translations but does not have to be.
|
||||
|
||||
`algolia` - Information for Algolia search integration. If this field is excluded, the search bar will not appear in the header.
|
||||
|
||||
|
@ -130,7 +130,7 @@ const siteConfig = {
|
|||
disableTitleTagline: true,
|
||||
separateCss: ["static/css/non-docusaurus", "static/assets/separate-css"],
|
||||
footerIcon: "img/docusaurus.svg",
|
||||
recruitingLink:
|
||||
translationRecruitingLink:
|
||||
"https://crowdin.com/project/docusaurus",
|
||||
algolia: {
|
||||
apiKey:
|
||||
|
|
|
@ -29,7 +29,7 @@ crowdin.yaml
|
|||
|
||||
The `pages/en/help-with-translations.js` file includes the same starter help page generated by the `examples` script, but now includes translation tags.
|
||||
|
||||
The `languages.js` file tells Docusaurus what languages you want to enable for your site.
|
||||
The `languages.js` file tells Docusaurus what languages you want to enable for your site. By default, we expect English to be enabled.
|
||||
|
||||
The `crowdin.yaml` file is used to configure crowdin integration, and is copied up one level into your docusaurus project repo. If your docusaurus project resides in `/project/website`, then `crowdin.yaml` will be copied to `/project/crowdin.yaml`.
|
||||
|
||||
|
@ -95,9 +95,9 @@ This section provides context about how translations in Docusaurus works.
|
|||
|
||||
### Strings
|
||||
|
||||
A Docusaurus site has many strings used throughout it that require localization. However, maintaining a list of strings used through out a site can be laborious. Docusaurus simplies this by centralizing strings.
|
||||
A Docusaurus site has many strings used throughout it that require localization. However, maintaining a list of strings used through out a site can be laborious. Docusaurus simplifies this by centralizing strings.
|
||||
|
||||
The header navigation, for example can have links to 'Home' or your 'Blog'. This and other strings found in the headers and sidebars of pages are extracted and placed into `i18n/en.json`. When your files are translated, say into Spanish, a `i18n/fr.json` file will be downloaded from Crowdin. Then, when the Spanish pages are generated, Docusaurus will replace the English version of corresponding strings with translated strings from the corresponding localized strings file (e.g. In a Spanish enabled site 'Help' will become 'Ayuda').
|
||||
The header navigation, for example can have links to 'Home' or your 'Blog'. This and other strings found in the headers and sidebars of pages are extracted and placed into `i18n/en.json`. When your files are translated, say into Spanish, a `i18n/es-ES.json` file will be downloaded from Crowdin. Then, when the Spanish pages are generated, Docusaurus will replace the English version of corresponding strings with translated strings from the corresponding localized strings file (e.g. In a Spanish enabled site 'Help' will become 'Ayuda').
|
||||
|
||||
### Markdown Files
|
||||
|
||||
|
@ -105,12 +105,45 @@ For documentation files themselves, translated versions of these files are downl
|
|||
|
||||
### Other Pages
|
||||
|
||||
For other pages, Docusaurus will automatically transform all `<translate>` tags it finds into function calls that return the translated strings from corresponding localized _`locale`_`.json`.
|
||||
For other pages, Docusaurus will automatically transform all `<translate>` tags it finds into function calls that return the translated strings from the corresponding localized file _`locale.json`_.
|
||||
|
||||
## Crowdin
|
||||
|
||||
Crowdin is a company that provides translation services. For Open Source projects, Crowdin provides free string translations
|
||||
|
||||
Create your translation project on [Crowdin](https://www.crowdin.com/). You can use [Crowdin's guides](https://support.crowdin.com/translation-process-overview/) to learn more about the translations work flow.
|
||||
|
||||
Your project will need a `crowdin.yaml` file generated.
|
||||
|
||||
The example below can be automatically generated by the docusaurus cli with the `examples` script. It should be placed in the top level of your project directory to configure how and what files are uploaded/downloaded.
|
||||
|
||||
Below is an example crowdin configuration for the respective languages: German, Spanish, French, Japanese, Korean, Behasa Indonesia, Portuguese Brazilian, Chinese Simplified, and Chinese Traditional.
|
||||
|
||||
```yaml
|
||||
project_identifier_env: CROWDIN_DOCUSAURUS_PROJECT_ID
|
||||
api_key_env: CROWDIN_DOCUSAURUS_API_KEY
|
||||
base_path: "./"
|
||||
preserve_hierarchy: true
|
||||
|
||||
files:
|
||||
-
|
||||
source: '/docs/*.md'
|
||||
translation: '/website/translated_docs/%locale%/%original_file_name%'
|
||||
languages_mapping: &anchor
|
||||
locale:
|
||||
'de': 'de'
|
||||
'es-ES': 'es-ES'
|
||||
'fr': 'fr'
|
||||
'ja': 'ja'
|
||||
'ko': 'ko'
|
||||
'mr': 'mr-IN'
|
||||
'pt-BR': 'pt-BR'
|
||||
'zh-CN': 'zh-Hans'
|
||||
'zh-TW': 'zh-Hant'
|
||||
```
|
||||
|
||||
You can [go here]() to learn more about customizing your `crowdin.yaml` file.
|
||||
|
||||
### Manual File Sync
|
||||
|
||||
You can add the following to your `package.json` to manually trigger crowdin.
|
||||
|
@ -124,11 +157,13 @@ You can add the following to your `package.json` to manually trigger crowdin.
|
|||
|
||||
These commands require having an environment variable set with your crowdin project id and api key (`CROWDIN_PROJECT_ID`, `CROWDIN_API_KEY`). You can add them inline like above or add them permanently to your `.bashrc` or `.bash_profile`.
|
||||
|
||||
If you run more than one localized Docusaurus project on your computer, you should change the name of the enviroment variables to something unique (`CROWDIN_DOCUSAURUS_PROJECT_ID`, `CROWDIN_DOCUSAURUS_API_KEY`).
|
||||
If you run more than one localized Docusaurus project on your computer, you should change the name of the enviroment variables to something unique (`CROWDIN_PROJECTNAME_PROJECT_ID`, `CROWDIN_PROJECTNAME_API_KEY`).
|
||||
|
||||
### Automated File Sync
|
||||
### Automated File Sync Using CircleCI
|
||||
|
||||
To automatically get the translations for your files, update the `circle.yml` file in your project directory to include steps to upload English files to be translated and download translated files using the Crowdin CLI. Here is an example `circle.yml` file:
|
||||
You can automate pulling down and uploading translations for your files using the [CircleCI](https://circleci.com) web continuous integration service.
|
||||
|
||||
First, update the `circle.yml` file in your project directory to include steps to upload English files to be translated and download translated files using the Crowdin CLI. Here is an example `circle.yml` file:
|
||||
|
||||
```yaml
|
||||
machine:
|
||||
|
|
|
@ -11,40 +11,38 @@ const Marked = require("./Marked.js");
|
|||
// inner doc component for article itself
|
||||
class Doc extends React.Component {
|
||||
render() {
|
||||
let editLink =
|
||||
!this.props.version &&
|
||||
this.props.config.editUrl &&
|
||||
let editLink = !this.props.version &&
|
||||
this.props.config.editUrl && (
|
||||
<a
|
||||
className="edit-page-link button"
|
||||
href={this.props.config.editUrl + this.props.source}
|
||||
target="_blank"
|
||||
>
|
||||
target="_blank">
|
||||
Edit this Doc
|
||||
</a>;
|
||||
</a>
|
||||
);
|
||||
if (this.props.language != "en") {
|
||||
editLink =
|
||||
!this.props.version &&
|
||||
this.props.config.recruitingLink &&
|
||||
editLink = !this.props.version &&
|
||||
this.props.config.translationRecruitingLink && (
|
||||
<a
|
||||
className="edit-page-link button"
|
||||
href={this.props.config.recruitingLink + "/" + this.props.language}
|
||||
target="_blank"
|
||||
>
|
||||
href={
|
||||
this.props.config.translationRecruitingLink +
|
||||
"/" +
|
||||
this.props.language
|
||||
}
|
||||
target="_blank">
|
||||
Translate this Doc
|
||||
</a>;
|
||||
</a>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div className="post">
|
||||
<header className="postHeader">
|
||||
{editLink}
|
||||
<h1>
|
||||
{this.props.title}
|
||||
</h1>
|
||||
<h1>{this.props.title}</h1>
|
||||
</header>
|
||||
<article>
|
||||
<Marked>
|
||||
{this.props.content}
|
||||
</Marked>
|
||||
<Marked>{this.props.content}</Marked>
|
||||
</article>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -31,6 +31,7 @@ class Site extends React.Component {
|
|||
this.props.config.baseUrl +
|
||||
(this.props.url || "index.html");
|
||||
let latestVersion;
|
||||
|
||||
if (fs.existsSync(CWD + "/versions.json")) {
|
||||
latestVersion = require(CWD + "/versions.json")[0];
|
||||
}
|
||||
|
@ -54,12 +55,13 @@ class Site extends React.Component {
|
|||
{this.props.children}
|
||||
<Footer config={this.props.config} language={this.props.language} />
|
||||
</div>
|
||||
{this.props.config.algolia &&
|
||||
{this.props.config.algolia && (
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="//cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js"
|
||||
/>}
|
||||
{this.props.config.gaTrackingId &&
|
||||
/>
|
||||
)}
|
||||
{this.props.config.gaTrackingId && (
|
||||
<script
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
|
@ -72,41 +74,45 @@ class Site extends React.Component {
|
|||
ga('send', 'pageview');
|
||||
`
|
||||
}}
|
||||
/>}
|
||||
{this.props.config.facebookAppId &&
|
||||
/>
|
||||
)}
|
||||
{this.props.config.facebookAppId && (
|
||||
<script
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `window.fbAsyncInit = function() {FB.init({appId:'${this.props.config.facebookAppId}',xfbml:true,version:'v2.7'});};(function(d, s, id){var js, fjs = d.getElementsByTagName(s)[0];if (d.getElementById(id)) {return;}js = d.createElement(s); js.id = id;js.src = '//connect.facebook.net/en_US/sdk.js';fjs.parentNode.insertBefore(js, fjs);}(document, 'script','facebook-jssdk'));
|
||||
`,
|
||||
__html: `window.fbAsyncInit = function() {FB.init({appId:'${this
|
||||
.props.config
|
||||
.facebookAppId}',xfbml:true,version:'v2.7'});};(function(d, s, id){var js, fjs = d.getElementsByTagName(s)[0];if (d.getElementById(id)) {return;}js = d.createElement(s); js.id = id;js.src = '//connect.facebook.net/en_US/sdk.js';fjs.parentNode.insertBefore(js, fjs);}(document, 'script','facebook-jssdk'));
|
||||
`
|
||||
}}
|
||||
/>
|
||||
}
|
||||
{this.props.config.twitter &&
|
||||
)}
|
||||
{this.props.config.twitter && (
|
||||
<script
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `window.twttr=(function(d,s, id){var js,fjs=d.getElementsByTagName(s)[0],t=window.twttr||{};if(d.getElementById(id))return t;js=d.createElement(s);js.id=id;js.src='https://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js, fjs);t._e = [];t.ready = function(f) {t._e.push(f);};return t;}(document, 'script', 'twitter-wjs'));`,
|
||||
__html: `window.twttr=(function(d,s, id){var js,fjs=d.getElementsByTagName(s)[0],t=window.twttr||{};if(d.getElementById(id))return t;js=d.createElement(s);js.id=id;js.src='https://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js, fjs);t._e = [];t.ready = function(f) {t._e.push(f);};return t;}(document, 'script', 'twitter-wjs'));`
|
||||
}}
|
||||
/>
|
||||
}
|
||||
)}
|
||||
{this.props.config.algolia &&
|
||||
(this.props.config.algolia.algoliaOptions
|
||||
? <script
|
||||
(this.props.config.algolia.algoliaOptions ? (
|
||||
<script
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
var search = docsearch({
|
||||
apiKey: '${this.props.config.algolia.apiKey}',
|
||||
indexName: '${this.props.config.algolia.indexName}',
|
||||
inputSelector: '#search_input_react',
|
||||
algoliaOptions: ${
|
||||
JSON.stringify(this.props.config.algolia.algoliaOptions)
|
||||
algoliaOptions: ${JSON.stringify(
|
||||
this.props.config.algolia.algoliaOptions
|
||||
)
|
||||
.replace("VERSION", this.props.version || latestVersion)
|
||||
.replace("LANGUAGE", this.props.language)
|
||||
}
|
||||
.replace("LANGUAGE", this.props.language)}
|
||||
});
|
||||
`
|
||||
}}
|
||||
/>
|
||||
: <script
|
||||
) : (
|
||||
<script
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
var search = docsearch({
|
||||
|
@ -116,7 +122,8 @@ class Site extends React.Component {
|
|||
});
|
||||
`
|
||||
}}
|
||||
/>)}
|
||||
/>
|
||||
))}
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
|
|
|
@ -12,13 +12,15 @@ const fs = require("fs");
|
|||
const siteConfig = require(CWD + "/siteConfig.js");
|
||||
const translation = require("../../server/translation.js");
|
||||
|
||||
const translate = require("../../server/translate.js").translate;
|
||||
|
||||
const ENABLE_TRANSLATION = fs.existsSync(CWD + "/languages.js");
|
||||
const ENABLE_VERSIONING = fs.existsSync(CWD + "/versions.json");
|
||||
let versions;
|
||||
if (ENABLE_VERSIONING) {
|
||||
versions = require(CWD + "/versions.json");
|
||||
}
|
||||
require("../../server/readMetadata.js").generateDocsMetadata();
|
||||
require("../../server/readMetadata.js").generateMetadataDocs();
|
||||
const Metadata = require("../metadata.js");
|
||||
|
||||
// language dropdown nav item for when translations are enabled
|
||||
|
@ -26,6 +28,9 @@ class LanguageDropDown extends React.Component {
|
|||
render() {
|
||||
const enabledLanguages = [];
|
||||
let currentLanguage = "English";
|
||||
let helpTranslateString = translate(
|
||||
"Help Translate|recruit community translators for your project"
|
||||
);
|
||||
// add all enabled languages to dropdown
|
||||
translation["languages"].map(lang => {
|
||||
if (lang.tag == this.props.language) {
|
||||
|
@ -36,9 +41,7 @@ class LanguageDropDown extends React.Component {
|
|||
}
|
||||
enabledLanguages.push(
|
||||
<li key={lang.tag}>
|
||||
<a href={siteConfig.baseUrl + lang.tag}>
|
||||
{lang.name}
|
||||
</a>
|
||||
<a href={siteConfig.baseUrl + lang.tag}>{lang.name}</a>
|
||||
</li>
|
||||
);
|
||||
});
|
||||
|
@ -47,11 +50,11 @@ class LanguageDropDown extends React.Component {
|
|||
return null;
|
||||
}
|
||||
// add Crowdin project recruiting link
|
||||
if (siteConfig.recruitingLink) {
|
||||
if (siteConfig.translationRecruitingLink) {
|
||||
enabledLanguages.push(
|
||||
<li key="recruiting">
|
||||
<a href={siteConfig.recruitingLink} target="_blank">
|
||||
Help Translate
|
||||
<a href={siteConfig.translationRecruitingLink} target="_blank">
|
||||
{helpTranslateString}
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
|
@ -68,9 +71,7 @@ class LanguageDropDown extends React.Component {
|
|||
{currentLanguage}
|
||||
</a>
|
||||
<div id="languages-dropdown" className="hide">
|
||||
<ul id="languages-dropdown-items">
|
||||
{enabledLanguages}
|
||||
</ul>
|
||||
<ul id="languages-dropdown-items">{enabledLanguages}</ul>
|
||||
</div>
|
||||
</li>
|
||||
<script
|
||||
|
@ -188,17 +189,15 @@ class HeaderNav extends React.Component {
|
|||
className="logo"
|
||||
src={this.props.baseUrl + siteConfig.headerIcon}
|
||||
/>
|
||||
{!this.props.config.disableHeaderTitle &&
|
||||
<h2 className="headerTitle">
|
||||
{this.props.title}
|
||||
</h2>}
|
||||
{!this.props.config.disableHeaderTitle && (
|
||||
<h2 className="headerTitle">{this.props.title}</h2>
|
||||
)}
|
||||
</a>
|
||||
{ENABLE_VERSIONING &&
|
||||
{ENABLE_VERSIONING && (
|
||||
<a href={versionsLink}>
|
||||
<h3>
|
||||
{this.props.version || versions[0]}
|
||||
</h3>
|
||||
</a>}
|
||||
<h3>{this.props.version || versions[0]}</h3>
|
||||
</a>
|
||||
)}
|
||||
{this.renderResponsiveNav()}
|
||||
</header>
|
||||
</div>
|
||||
|
|
|
@ -25,7 +25,7 @@ let readMetadata;
|
|||
let Metadata;
|
||||
|
||||
readMetadata = require("./readMetadata.js");
|
||||
readMetadata.generateDocsMetadata();
|
||||
readMetadata.generateMetadataDocs();
|
||||
Metadata = require("../core/metadata.js");
|
||||
|
||||
/****************************************************************************/
|
||||
|
@ -35,7 +35,7 @@ module.exports = function(type) {
|
|||
|
||||
type = type || "rss";
|
||||
|
||||
readMetadata.generateBlogMetadata();
|
||||
readMetadata.generateMetadataBlog();
|
||||
const MetadataBlog = require("../core/MetadataBlog.js");
|
||||
|
||||
const feed = new Feed({
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
*/
|
||||
|
||||
function execute() {
|
||||
const extractTranslations = require("../write-translations.js");
|
||||
|
||||
const CWD = process.cwd();
|
||||
const fs = require("fs-extra");
|
||||
const readMetadata = require("./readMetadata.js");
|
||||
|
@ -22,6 +24,7 @@ function execute() {
|
|||
const versionFallback = require("./versionFallback.js");
|
||||
|
||||
const feed = require("./feed.js");
|
||||
const sitemap = require("./sitemap.js");
|
||||
|
||||
const ENABLE_TRANSLATION = fs.existsSync(CWD + "/languages.js");
|
||||
const ENABLE_VERSIONING = fs.existsSync(CWD + "/versions.json");
|
||||
|
@ -86,7 +89,7 @@ function execute() {
|
|||
enabledLanguages.push(lang.tag);
|
||||
});
|
||||
|
||||
readMetadata.generateDocsMetadata();
|
||||
readMetadata.generateMetadataDocs();
|
||||
const Metadata = require("../core/metadata.js");
|
||||
|
||||
// mdToHtml is a map from a markdown file name to its html link, used to
|
||||
|
@ -205,12 +208,15 @@ function execute() {
|
|||
if (fs.existsSync(__dirname + "../core/MetadataBlog.js")) {
|
||||
fs.removeSync(__dirname + "../core/MetadataBlog.js");
|
||||
}
|
||||
readMetadata.generateBlogMetadata();
|
||||
readMetadata.generateMetadataBlog();
|
||||
const MetadataBlog = require("../core/MetadataBlog.js");
|
||||
const BlogPostLayout = require("../core/BlogPostLayout.js");
|
||||
|
||||
let files = glob.sync(CWD + "/blog/**/*.*");
|
||||
files.sort().reverse().forEach(file => {
|
||||
files
|
||||
.sort()
|
||||
.reverse()
|
||||
.forEach(file => {
|
||||
const extension = path.extname(file);
|
||||
if (extension !== ".md" && extension !== ".markdown") {
|
||||
return;
|
||||
|
@ -225,11 +231,11 @@ function execute() {
|
|||
.replace(/\./g, "-")
|
||||
.replace(/\-md$/, ".html");
|
||||
const result = readMetadata.extractMetadata(
|
||||
fs.readFileSync(file, {encoding: "utf8"})
|
||||
fs.readFileSync(file, { encoding: "utf8" })
|
||||
);
|
||||
const rawContent = result.rawContent;
|
||||
const metadata = Object.assign(
|
||||
{path: filePath, content: rawContent},
|
||||
{ path: filePath, content: rawContent },
|
||||
result.metadata
|
||||
);
|
||||
metadata.id = metadata.title;
|
||||
|
@ -239,8 +245,7 @@ function execute() {
|
|||
<BlogPostLayout
|
||||
metadata={metadata}
|
||||
language={language}
|
||||
config={siteConfig}
|
||||
>
|
||||
config={siteConfig}>
|
||||
{rawContent}
|
||||
</BlogPostLayout>
|
||||
);
|
||||
|
@ -255,7 +260,7 @@ function execute() {
|
|||
const perPage = 10;
|
||||
for (let page = 0; page < Math.ceil(MetadataBlog.length / perPage); page++) {
|
||||
let language = "en";
|
||||
const metadata = {page: page, perPage: perPage};
|
||||
const metadata = { page: page, perPage: perPage };
|
||||
const blogPageComp = (
|
||||
<BlogPageLayout
|
||||
metadata={metadata}
|
||||
|
@ -277,13 +282,20 @@ function execute() {
|
|||
// create rss files for all blog pages, if there are any blog files
|
||||
if (MetadataBlog.length > 0) {
|
||||
let targetFile =
|
||||
CWD + "/build/" + siteConfig.projectName + "/blog/" + "feed.xml";
|
||||
CWD + "/build/" + siteConfig.projectName + "/blog/feed.xml";
|
||||
writeFileAndCreateFolder(targetFile, feed());
|
||||
targetFile =
|
||||
CWD + "/build/" + siteConfig.projectName + "/blog/" + "atom.xml";
|
||||
targetFile = CWD + "/build/" + siteConfig.projectName + "/blog/atom.xml";
|
||||
writeFileAndCreateFolder(targetFile, feed("atom"));
|
||||
}
|
||||
|
||||
// create sitemap
|
||||
if (MetadataBlog.length > 0 && Object.keys(Metadata).length > 0) {
|
||||
let targetFile = CWD + "/build/" + siteConfig.projectName + "/sitemap.xml";
|
||||
sitemap(xml => {
|
||||
writeFileAndCreateFolder(targetFile, xml);
|
||||
});
|
||||
}
|
||||
|
||||
// copy blog assets if they exist
|
||||
if (fs.existsSync(CWD + "/blog/assets")) {
|
||||
fs.copySync(
|
||||
|
@ -357,6 +369,7 @@ function execute() {
|
|||
});
|
||||
|
||||
// compile/copy pages from user
|
||||
let pagesArr = [];
|
||||
files = glob.sync(CWD + "/pages/**");
|
||||
files.forEach(file => {
|
||||
// render .js files to strings
|
||||
|
|
|
@ -92,20 +92,23 @@ function extractMetadata(content) {
|
|||
const metadata = {};
|
||||
const both = splitHeader(content);
|
||||
if (both === false) {
|
||||
return {metadata, rawContent: content};
|
||||
return { metadata, rawContent: content };
|
||||
}
|
||||
const lines = both.header.split("\n");
|
||||
for (let i = 0; i < lines.length - 1; ++i) {
|
||||
const keyvalue = lines[i].split(":");
|
||||
const key = keyvalue[0].trim();
|
||||
let value = keyvalue.slice(1).join(":").trim();
|
||||
let value = keyvalue
|
||||
.slice(1)
|
||||
.join(":")
|
||||
.trim();
|
||||
try {
|
||||
value = JSON.parse(value);
|
||||
} catch (e) {}
|
||||
metadata[key] = value;
|
||||
}
|
||||
|
||||
return {metadata, rawContent: both.content};
|
||||
return { metadata, rawContent: both.content };
|
||||
}
|
||||
|
||||
// process the metadata for a document found in the docs folder
|
||||
|
@ -174,11 +177,11 @@ function processMetadata(file) {
|
|||
}
|
||||
}
|
||||
|
||||
return {metadata, rawContent: rawContent};
|
||||
return { metadata, rawContent: rawContent };
|
||||
}
|
||||
|
||||
// process metadata for all docs and save into core/metadata.js
|
||||
function generateDocsMetadata() {
|
||||
function generateMetadataDocs() {
|
||||
const order = readSidebar();
|
||||
|
||||
const regexSubFolder = /translated_docs\/(.*)\/.*/;
|
||||
|
@ -269,7 +272,7 @@ function generateDocsMetadata() {
|
|||
}
|
||||
|
||||
// process metadata for blog posts and save into core/MetadataBlog.js
|
||||
function generateBlogMetadata() {
|
||||
function generateMetadataBlog() {
|
||||
const metadatas = [];
|
||||
|
||||
let files = glob.sync(CWD + "/blog/**/*.*");
|
||||
|
@ -280,7 +283,10 @@ function generateBlogMetadata() {
|
|||
)} Make sure you've put your blog files in your Docusaurus 'website' folder.`
|
||||
);
|
||||
}
|
||||
files.sort().reverse().forEach(file => {
|
||||
files
|
||||
.sort()
|
||||
.reverse()
|
||||
.forEach(file => {
|
||||
const extension = path.extname(file);
|
||||
if (extension !== ".md" && extension !== ".markdown") {
|
||||
return;
|
||||
|
@ -296,17 +302,22 @@ function generateBlogMetadata() {
|
|||
.replace("-", "/")
|
||||
.replace(/\./g, "-")
|
||||
.replace(/\-md$/, ".html");
|
||||
const result = extractMetadata(fs.readFileSync(file, {encoding: "utf8"}));
|
||||
const result = extractMetadata(
|
||||
fs.readFileSync(file, { encoding: "utf8" })
|
||||
);
|
||||
const rawContent = result.rawContent;
|
||||
const metadata = Object.assign(
|
||||
{path: filePath, content: rawContent},
|
||||
{ path: filePath, content: rawContent },
|
||||
result.metadata
|
||||
);
|
||||
|
||||
metadata.id = metadata.title;
|
||||
|
||||
// Extract, YYYY, MM, DD from the file name
|
||||
let filePathDateArr = path.basename(file).toString().split("-");
|
||||
let filePathDateArr = path
|
||||
.basename(file)
|
||||
.toString()
|
||||
.split("-");
|
||||
metadata.date = new Date(
|
||||
filePathDateArr[0] +
|
||||
"-" +
|
||||
|
@ -334,6 +345,6 @@ module.exports = {
|
|||
readSidebar,
|
||||
extractMetadata,
|
||||
processMetadata,
|
||||
generateDocsMetadata,
|
||||
generateBlogMetadata
|
||||
generateMetadataDocs,
|
||||
generateMetadataBlog
|
||||
};
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/**
|
||||
|
||||
* Copyright (c) 2017-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
|
@ -6,6 +7,8 @@
|
|||
*/
|
||||
|
||||
function execute(port) {
|
||||
const extractTranslations = require("../write-translations.js");
|
||||
|
||||
const translation = require("./translation.js");
|
||||
const express = require("express");
|
||||
const React = require("react");
|
||||
|
@ -22,6 +25,8 @@ function execute(port) {
|
|||
const versionFallback = require("./versionFallback");
|
||||
|
||||
const feed = require("./feed.js");
|
||||
const sitemap = require("./sitemap.js");
|
||||
// const sitemap = require("sitemap");
|
||||
|
||||
const CWD = process.cwd();
|
||||
const ENABLE_TRANSLATION = fs.existsSync(CWD + "/languages.js");
|
||||
|
@ -53,17 +58,31 @@ function execute(port) {
|
|||
|
||||
/****************************************************************************/
|
||||
|
||||
let readMetadata;
|
||||
let readMetadata = require("./readMetadata.js");
|
||||
let Metadata;
|
||||
let MetadataBlog;
|
||||
|
||||
function reloadMetadata() {
|
||||
removeModuleAndChildrenFromCache("./readMetadata.js");
|
||||
readMetadata = require("./readMetadata.js");
|
||||
readMetadata.generateDocsMetadata();
|
||||
readMetadata.generateMetadataDocs();
|
||||
removeModuleAndChildrenFromCache("../core/metadata.js");
|
||||
Metadata = require("../core/metadata.js");
|
||||
}
|
||||
|
||||
function reloadMetadataBlog() {
|
||||
if (fs.existsSync(__dirname + "/../core/MetadataBlog.js")) {
|
||||
removeModuleAndChildrenFromCache("../core/MetadataBlog.js");
|
||||
fs.removeSync(__dirname + "/../core/MetadataBlog.js");
|
||||
}
|
||||
readMetadata.generateMetadataBlog();
|
||||
MetadataBlog = require("../core/MetadataBlog.js");
|
||||
}
|
||||
|
||||
function reloadSiteConfig() {
|
||||
removeModuleAndChildrenFromCache(CWD + "/siteConfig.js");
|
||||
siteConfig = require(CWD + "/siteConfig.js");
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
const TABLE_OF_CONTENTS_TOKEN = "<AUTOGENERATED_TABLE_OF_CONTENTS>";
|
||||
|
@ -105,9 +124,8 @@ function execute(port) {
|
|||
|
||||
// handle all requests for document pages
|
||||
const app = express().get(/docs\/.*html$/, (req, res, next) => {
|
||||
removeModuleAndChildrenFromCache(CWD + "/siteConfig.js");
|
||||
siteConfig = require(CWD + "/siteConfig.js");
|
||||
|
||||
extractTranslations();
|
||||
reloadSiteConfig();
|
||||
let url = req.path.toString().replace(siteConfig.baseUrl, "");
|
||||
|
||||
reloadMetadata();
|
||||
|
@ -230,6 +248,23 @@ function execute(port) {
|
|||
res.send(renderToStaticMarkup(docComp));
|
||||
});
|
||||
|
||||
app.get("/sitemap.xml", function(req, res) {
|
||||
res.set("Content-Type", "application/xml");
|
||||
|
||||
sitemap(xml => {
|
||||
res.send(xml);
|
||||
});
|
||||
});
|
||||
app.get(/blog\/.*xml$/, (req, res) => {
|
||||
res.set("Content-Type", "application/rss+xml");
|
||||
let parts = req.path.toString().split("blog/");
|
||||
if (parts[1].toLowerCase() == "atom.xml") {
|
||||
res.send(feed("atom"));
|
||||
return;
|
||||
}
|
||||
res.send(feed("rss"));
|
||||
});
|
||||
|
||||
app.get(/blog\/.*xml$/, (req, res) => {
|
||||
res.set("Content-Type", "application/rss+xml");
|
||||
let parts = req.path.toString().split("blog/");
|
||||
|
@ -242,14 +277,9 @@ function execute(port) {
|
|||
|
||||
// handle all requests for blog pages and posts
|
||||
app.get(/blog\/.*html$/, (req, res) => {
|
||||
removeModuleAndChildrenFromCache(CWD + "/siteConfig.js");
|
||||
siteConfig = require(CWD + "/siteConfig.js");
|
||||
if (fs.existsSync(__dirname + "/../core/MetadataBlog.js")) {
|
||||
removeModuleAndChildrenFromCache("../core/MetadataBlog.js");
|
||||
fs.removeSync(__dirname + "/../core/MetadataBlog.js");
|
||||
}
|
||||
readMetadata.generateBlogMetadata();
|
||||
const MetadataBlog = require("../core/MetadataBlog.js");
|
||||
extractTranslations();
|
||||
reloadSiteConfig();
|
||||
reloadMetadataBlog();
|
||||
|
||||
// generate all of the blog pages
|
||||
removeModuleAndChildrenFromCache("../core/BlogPageLayout.js");
|
||||
|
@ -318,8 +348,7 @@ function execute(port) {
|
|||
<BlogPostLayout
|
||||
metadata={metadata}
|
||||
language={language}
|
||||
config={siteConfig}
|
||||
>
|
||||
config={siteConfig}>
|
||||
{rawContent}
|
||||
</BlogPostLayout>
|
||||
);
|
||||
|
@ -329,8 +358,8 @@ function execute(port) {
|
|||
|
||||
// handle all other main pages
|
||||
app.get("*.html", (req, res, next) => {
|
||||
removeModuleAndChildrenFromCache(CWD + "/siteConfig.js");
|
||||
siteConfig = require(CWD + "/siteConfig.js");
|
||||
extractTranslations();
|
||||
reloadSiteConfig();
|
||||
|
||||
// look for user provided html file first
|
||||
let htmlFile = req.path.toString().replace(siteConfig.baseUrl, "");
|
||||
|
@ -371,7 +400,7 @@ function execute(port) {
|
|||
englishFile = englishFile.replace("/" + language + "/", "/en/");
|
||||
}
|
||||
|
||||
// check for: a file for the page, an english file for page with unspecified language,
|
||||
// check for: a file for the page, an english file for page with unspecified language, or an
|
||||
// english file for the page
|
||||
if (
|
||||
fs.existsSync(userFile) ||
|
||||
|
|
94
lib/server/sitemap.js
Normal file
94
lib/server/sitemap.js
Normal file
|
@ -0,0 +1,94 @@
|
|||
/**
|
||||
* Copyright (c) 2017-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
const fs = require("fs-extra");
|
||||
const path = require("path");
|
||||
const os = require("os");
|
||||
const Feed = require("feed");
|
||||
|
||||
const chalk = require("chalk");
|
||||
const glob = require("glob");
|
||||
const CWD = process.cwd();
|
||||
|
||||
const sitemap = require("sitemap");
|
||||
|
||||
const siteConfig = require(CWD + "/siteConfig.js");
|
||||
|
||||
const blogFolder = path.resolve("../blog/");
|
||||
const blogRootURL = siteConfig.url + "/blog";
|
||||
const jestImage = siteConfig.url + siteConfig.headerIcon;
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
let readMetadata;
|
||||
let Metadata;
|
||||
let MetadataBlog;
|
||||
|
||||
readMetadata = require("./readMetadata.js");
|
||||
readMetadata.generateMetadataDocs();
|
||||
Metadata = require("../core/metadata.js");
|
||||
readMetadata.generateMetadataBlog();
|
||||
MetadataBlog = require("../core/MetadataBlog.js");
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
module.exports = function(callback) {
|
||||
console.log("sitemap.js triggered...");
|
||||
|
||||
let urls = [];
|
||||
|
||||
let files = glob.sync(CWD + "/pages/**/*.js");
|
||||
|
||||
let languages = null;
|
||||
|
||||
languages = require(CWD + "/languages.js");
|
||||
|
||||
let enabledLanguages = languages.filter(lang => {
|
||||
return lang.enabled == true;
|
||||
});
|
||||
|
||||
files.map(file => {
|
||||
enabledLanguages.map(lang => {
|
||||
let url = file.split("/pages/en")[1];
|
||||
let tag = "";
|
||||
if (lang.tag != "en") {
|
||||
tag = lang.tag;
|
||||
}
|
||||
url = tag + url;
|
||||
url = url.replace(/\.js$/, ".html");
|
||||
urls.push({ url: "/" + url, changefreq: "weekly", priority: 0.5 });
|
||||
});
|
||||
});
|
||||
|
||||
let htmlFiles = glob.sync(CWD + "/pages/**/*.html");
|
||||
|
||||
MetadataBlog.map(blog => {
|
||||
urls.push({
|
||||
url: "/blog/" + blog.path,
|
||||
changefreq: "weekly",
|
||||
priority: 0.3
|
||||
});
|
||||
});
|
||||
|
||||
Object.keys(Metadata).map(key => {
|
||||
let doc = Metadata[key];
|
||||
urls.push({ url: doc.permalink, changefreq: "hourly", priority: 1.0 });
|
||||
});
|
||||
|
||||
const sm = sitemap.createSitemap({
|
||||
hostname: siteConfig.url,
|
||||
cacheTime: 600 * 1000, // 600 sec - cache purge period
|
||||
urls: urls
|
||||
});
|
||||
|
||||
sm.toXML((err, xml) => {
|
||||
if (err) {
|
||||
return "An error has occured.";
|
||||
}
|
||||
callback(xml);
|
||||
});
|
||||
};
|
|
@ -33,12 +33,11 @@ function translate(str) {
|
|||
!translation[language]["pages-strings"][str]
|
||||
) {
|
||||
throw new Error(
|
||||
"Text that you've identified for translation hasn't been added to the global list in 'en.json'. To solve this problem run 'yarn write-translations'."
|
||||
"Text that you've identified for translation ('" +
|
||||
str +
|
||||
"') hasn't been added to the global list in 'en.json'. To solve this problem run 'yarn write-translations'."
|
||||
);
|
||||
}
|
||||
console.log(translation[language]);
|
||||
console.log(translation[language]["pages-strings"]);
|
||||
console.log(translation[language]["pages-strings"][str]);
|
||||
return parseEscapeSequences(translation[language]["pages-strings"][str]);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,8 @@ const translation = { languages: enabledLanguages };
|
|||
const files = glob.sync(CWD + "/i18n/**");
|
||||
const langRegex = /\/i18n\/(.*)\.json$/;
|
||||
|
||||
console.log("Loading translation files...");
|
||||
|
||||
files.forEach(file => {
|
||||
const extension = path.extname(file);
|
||||
if (extension === ".json") {
|
||||
|
|
|
@ -26,7 +26,7 @@ function writeFileAndCreateFolder(file, content) {
|
|||
}
|
||||
|
||||
function execute() {
|
||||
console.log("Writing translation files...");
|
||||
console.log("Extracting translateable strings from files...");
|
||||
|
||||
let translations = {
|
||||
"localized-strings": {
|
||||
|
@ -85,36 +85,11 @@ function execute() {
|
|||
});
|
||||
});
|
||||
|
||||
// go through pages to look for text inside translate tags
|
||||
files = glob.sync(CWD + "/pages/en/**");
|
||||
files.forEach(file => {
|
||||
const extension = path.extname(file);
|
||||
if (extension === ".js") {
|
||||
const ast = babylon.parse(fs.readFileSync(file, "utf8"), {
|
||||
plugins: ["jsx"]
|
||||
});
|
||||
traverse(ast, {
|
||||
enter(path) {
|
||||
if (
|
||||
path.node.type === "JSXElement" &&
|
||||
path.node.openingElement.name.name === "translate"
|
||||
) {
|
||||
const text = path.node.children[0].value
|
||||
.trim()
|
||||
.replace(/\s+/g, " ");
|
||||
let description = "no description given";
|
||||
const attributes = path.node.openingElement.attributes;
|
||||
for (let i = 0; i < attributes.length; i++) {
|
||||
if (attributes[i].name.name === "desc") {
|
||||
description = attributes[i].value.value;
|
||||
}
|
||||
}
|
||||
translations["pages-strings"][text + "|" + description] = text;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
// Manually add 'Help Translate' to en.json
|
||||
translations["pages-strings"][
|
||||
"Help Translate|recruit community translators for your project"
|
||||
] =
|
||||
"Help Translate";
|
||||
writeFileAndCreateFolder(
|
||||
CWD + "/i18n/en.json",
|
||||
JSON.stringify(translations, null, 2)
|
||||
|
@ -122,3 +97,5 @@ function execute() {
|
|||
}
|
||||
|
||||
execute();
|
||||
|
||||
module.exports = execute;
|
||||
|
|
|
@ -19,7 +19,8 @@
|
|||
"react-dom": "^15.5.4",
|
||||
"react-dom-factories": "^1.0.1",
|
||||
"request": "^2.81.0",
|
||||
"shelljs": "^0.7.8"
|
||||
"shelljs": "^0.7.8",
|
||||
"sitemap": "^1.13.0"
|
||||
},
|
||||
"name": "docusaurus",
|
||||
"version": "1.0.0-beta.1",
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
"site-config": "siteConfig.js",
|
||||
"installation": "Installation",
|
||||
"site-preparation": "Site Preparation",
|
||||
"publish": "Publishing Your Website",
|
||||
"publishing": "Publishing your site",
|
||||
"site-creation": "Creating your site",
|
||||
"blog": "Adding a Blog",
|
||||
"custom-pages": "Custom Pages",
|
||||
|
@ -25,5 +25,7 @@
|
|||
"Guides": "Guides",
|
||||
"API": "API"
|
||||
},
|
||||
"pages-strings": {}
|
||||
"pages-strings": {
|
||||
"Help Translate|recruit community translators for your project": "Help Translate"
|
||||
}
|
||||
}
|
|
@ -7,7 +7,13 @@
|
|||
"write-translations": "../lib/write-translations.js",
|
||||
"version": "../lib/version.js",
|
||||
"rename-version": "../lib/rename-version.js",
|
||||
"crowdin-upload": "crowdin-cli --config ../crowdin.yaml upload sources --auto-update -b master",
|
||||
"crowdin-download": "crowdin-cli --config ../crowdin.yaml download -b master"
|
||||
"crowdin-upload":
|
||||
"crowdin-cli --config ../crowdin.yaml upload sources --auto-update -b master",
|
||||
"crowdin-download":
|
||||
"crowdin-cli --config ../crowdin.yaml download -b master"
|
||||
},
|
||||
"dependencies": {
|
||||
"async": "^2.5.0",
|
||||
"docusaurus": "^1.0.0-alpha.42"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@ const GridBlock = CompLibrary.GridBlock;
|
|||
|
||||
const siteConfig = require(process.cwd() + "/siteConfig.js");
|
||||
|
||||
const translate = require("../../server/translate.js").translate;
|
||||
|
||||
class Button extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
|
@ -42,9 +44,7 @@ class HomeSplash extends React.Component {
|
|||
<div className="inner">
|
||||
<h2 className="projectTitle">
|
||||
{siteConfig.title}
|
||||
<small>
|
||||
{siteConfig.tagline}
|
||||
</small>
|
||||
<small>{siteConfig.tagline}</small>
|
||||
</h2>
|
||||
<div className="section promoSection">
|
||||
<div className="promoRow">
|
||||
|
@ -52,8 +52,7 @@ class HomeSplash extends React.Component {
|
|||
<Button
|
||||
href={`
|
||||
${siteConfig.baseUrl}docs/installation.html
|
||||
`}
|
||||
>
|
||||
`}>
|
||||
Get Started
|
||||
</Button>
|
||||
</div>
|
||||
|
@ -181,18 +180,13 @@ class Index extends React.Component {
|
|||
</Container>
|
||||
|
||||
<div className="productShowcaseSection paddingBottom">
|
||||
<h2>
|
||||
{"Who's Using This?"}
|
||||
</h2>
|
||||
<h2>{"Who's Using This?"}</h2>
|
||||
<p>Docusaurus is building websites for these projects</p>
|
||||
<div className="logos">
|
||||
{showcase}
|
||||
</div>
|
||||
<div className="logos">{showcase}</div>
|
||||
<div className="more-users">
|
||||
<a
|
||||
className="button"
|
||||
href={`${siteConfig.baseUrl}${this.props.language}/users.html`}
|
||||
>
|
||||
href={`${siteConfig.baseUrl}${this.props.language}/users.html`}>
|
||||
All Docusaurus Users
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
@ -42,7 +42,6 @@ const siteConfig = {
|
|||
{ doc: "installation", label: "Docs" },
|
||||
{ page: "help", label: "Help" },
|
||||
{ blog: true, label: "Blog" },
|
||||
{ languages: false },
|
||||
{
|
||||
href: "https://github.com/facebookexperimental/docusaurus",
|
||||
label: "GitHub"
|
||||
|
@ -61,6 +60,7 @@ const siteConfig = {
|
|||
secondaryColor: "#205C3B",
|
||||
prismColor: "rgba(46, 133, 85, 0.03)"
|
||||
},
|
||||
translationRecruitingLink: "https://crowdin.com/project/docusaurus",
|
||||
copyright: "Copyright © " + new Date().getFullYear() + " Facebook Inc."
|
||||
};
|
||||
|
||||
|
|
83
yarn.lock
83
yarn.lock
|
@ -134,6 +134,14 @@ babel-helper-builder-binary-assignment-operator-visitor@^6.24.1:
|
|||
babel-runtime "^6.22.0"
|
||||
babel-types "^6.24.1"
|
||||
|
||||
babel-helper-builder-react-jsx@^6.24.1:
|
||||
version "6.26.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz#39ff8313b75c8b65dceff1f31d383e0ff2a408a0"
|
||||
dependencies:
|
||||
babel-runtime "^6.26.0"
|
||||
babel-types "^6.26.0"
|
||||
esutils "^2.0.2"
|
||||
|
||||
babel-helper-call-delegate@^6.24.1:
|
||||
version "6.24.1"
|
||||
resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d"
|
||||
|
@ -247,6 +255,14 @@ babel-plugin-syntax-exponentiation-operator@^6.8.0:
|
|||
version "6.13.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de"
|
||||
|
||||
babel-plugin-syntax-flow@^6.18.0:
|
||||
version "6.18.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d"
|
||||
|
||||
babel-plugin-syntax-jsx@^6.3.13, babel-plugin-syntax-jsx@^6.8.0:
|
||||
version "6.18.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946"
|
||||
|
||||
babel-plugin-syntax-trailing-function-commas@^6.22.0:
|
||||
version "6.22.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3"
|
||||
|
@ -435,6 +451,41 @@ babel-plugin-transform-exponentiation-operator@^6.22.0:
|
|||
babel-plugin-syntax-exponentiation-operator "^6.8.0"
|
||||
babel-runtime "^6.22.0"
|
||||
|
||||
babel-plugin-transform-flow-strip-types@^6.22.0:
|
||||
version "6.22.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz#84cb672935d43714fdc32bce84568d87441cf7cf"
|
||||
dependencies:
|
||||
babel-plugin-syntax-flow "^6.18.0"
|
||||
babel-runtime "^6.22.0"
|
||||
|
||||
babel-plugin-transform-react-display-name@^6.23.0:
|
||||
version "6.25.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz#67e2bf1f1e9c93ab08db96792e05392bf2cc28d1"
|
||||
dependencies:
|
||||
babel-runtime "^6.22.0"
|
||||
|
||||
babel-plugin-transform-react-jsx-self@^6.22.0:
|
||||
version "6.22.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.22.0.tgz#df6d80a9da2612a121e6ddd7558bcbecf06e636e"
|
||||
dependencies:
|
||||
babel-plugin-syntax-jsx "^6.8.0"
|
||||
babel-runtime "^6.22.0"
|
||||
|
||||
babel-plugin-transform-react-jsx-source@^6.22.0:
|
||||
version "6.22.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.22.0.tgz#66ac12153f5cd2d17b3c19268f4bf0197f44ecd6"
|
||||
dependencies:
|
||||
babel-plugin-syntax-jsx "^6.8.0"
|
||||
babel-runtime "^6.22.0"
|
||||
|
||||
babel-plugin-transform-react-jsx@^6.24.1:
|
||||
version "6.24.1"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz#840a028e7df460dfc3a2d29f0c0d91f6376e66a3"
|
||||
dependencies:
|
||||
babel-helper-builder-react-jsx "^6.24.1"
|
||||
babel-plugin-syntax-jsx "^6.8.0"
|
||||
babel-runtime "^6.22.0"
|
||||
|
||||
babel-plugin-transform-regenerator@^6.22.0:
|
||||
version "6.26.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f"
|
||||
|
@ -483,6 +534,23 @@ babel-preset-env@^1.6.0:
|
|||
invariant "^2.2.2"
|
||||
semver "^5.3.0"
|
||||
|
||||
babel-preset-flow@^6.23.0:
|
||||
version "6.23.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz#e71218887085ae9a24b5be4169affb599816c49d"
|
||||
dependencies:
|
||||
babel-plugin-transform-flow-strip-types "^6.22.0"
|
||||
|
||||
babel-preset-react@^6.24.1:
|
||||
version "6.24.1"
|
||||
resolved "https://registry.yarnpkg.com/babel-preset-react/-/babel-preset-react-6.24.1.tgz#ba69dfaea45fc3ec639b6a4ecea6e17702c91380"
|
||||
dependencies:
|
||||
babel-plugin-syntax-jsx "^6.3.13"
|
||||
babel-plugin-transform-react-display-name "^6.23.0"
|
||||
babel-plugin-transform-react-jsx "^6.24.1"
|
||||
babel-plugin-transform-react-jsx-self "^6.22.0"
|
||||
babel-plugin-transform-react-jsx-source "^6.22.0"
|
||||
babel-preset-flow "^6.23.0"
|
||||
|
||||
babel-register@^6.24.1, babel-register@^6.26.0:
|
||||
version "6.26.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071"
|
||||
|
@ -1466,6 +1534,13 @@ shelljs@^0.7.8:
|
|||
interpret "^1.0.0"
|
||||
rechoir "^0.6.2"
|
||||
|
||||
sitemap@^1.13.0:
|
||||
version "1.13.0"
|
||||
resolved "https://registry.yarnpkg.com/sitemap/-/sitemap-1.13.0.tgz#569cbe2180202926a62a266cd3de09c9ceb43f83"
|
||||
dependencies:
|
||||
underscore "^1.7.0"
|
||||
url-join "^1.1.0"
|
||||
|
||||
slash@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
|
||||
|
@ -1569,6 +1644,10 @@ ua-parser-js@^0.7.9:
|
|||
version "0.7.14"
|
||||
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.14.tgz#110d53fa4c3f326c121292bbeac904d2e03387ca"
|
||||
|
||||
underscore@^1.7.0:
|
||||
version "1.8.3"
|
||||
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022"
|
||||
|
||||
universalify@^0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7"
|
||||
|
@ -1577,6 +1656,10 @@ unpipe@~1.0.0:
|
|||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
|
||||
|
||||
url-join@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/url-join/-/url-join-1.1.0.tgz#741c6c2f4596c4830d6718460920d0c92202dc78"
|
||||
|
||||
utils-merge@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.0.tgz#0294fb922bb9375153541c4f7096231f287c8af8"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue