From 2e7ee6bb8b0e21a1a16a71d88433e784811cda6d Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Thu, 28 Sep 2017 23:38:01 -0600 Subject: [PATCH] Updated docs --- ...3-code-of-conduct.md => CODE_OF_CONDUCT.md | 11 +- ...2-contributors-guide.md => CONTRIBUTING.md | 26 +- README.md | 24 +- docs/.gitignore | 7 +- docs/404.html | 22 + docs/Gemfile | 27 +- docs/Gemfile.lock | 192 +- docs/LICENSE.txt | 21 - docs/Rakefile | 75 - docs/_config.yml | 269 +- docs/_data/badges.yaml | 13 + docs/_data/nav.yaml | 19 + docs/_data/navigation.yml | 74 - docs/_data/ui-text.yml | 802 ----- docs/_docs/00-01-faq.md | 117 - docs/_docs/01-01-install.md | 21 - docs/_docs/01-02-install-docker.md | 150 - docs/_docs/01-03-install-source.md | 77 - docs/_docs/01-04-install-setup.md | 36 - docs/_docs/01-05-install-microservices.md | 95 - docs/_docs/01-06-install-troubleshooting.md | 19 - docs/_docs/02-01-configuration.md | 229 -- docs/_docs/02-02-secrets.md | 111 - docs/_docs/02-03-plugins.md | 25 - docs/_docs/02-04-migrations.md | 15 - docs/_docs/02-05-persistence.md | 50 - docs/_docs/03-01-architecture.md | 77 - docs/_docs/03-02-architecture-tags.md | 68 - docs/_docs/03-03-architecture-metadata.md | 89 - docs/_docs/03-04-architecture-cli.md | 136 - docs/_docs/03-05-client-architecture.md | 117 - docs/_docs/04-02-plugins-quickstart.md | 241 -- docs/_docs/04-03-plugins-client.md | 331 -- docs/_docs/04-04-plugins-server.md | 494 --- docs/_docs/04-05-plugins-experimental.md | 60 - docs/_docs/05-01-development-tools.md | 33 - docs/_docs/05-04-rest-api.md | 6 - docs/_docs/installation-from-docker.md | 122 + docs/_docs/installation-from-source.md | 80 + docs/_docs/installation-talk-quickstart.md | 185 ++ .../{04-01-plugins.md => plugins-overview.md} | 33 +- docs/_docs/running-advanced-configuration.md | 442 +++ docs/_docs/running-required-configuration.md | 106 + .../_includes/analytics-providers/custom.html | 3 - .../analytics-providers/google-universal.html | 9 - .../_includes/analytics-providers/google.html | 11 - docs/_includes/analytics.html | 12 - docs/_includes/archive-single.html | 38 - .../author-profile-custom-links.html | 7 - docs/_includes/author-profile.html | 249 -- docs/_includes/badges.html | 3 + docs/_includes/base_path | 5 - docs/_includes/breadcrumbs.html | 39 - docs/_includes/browser-upgrade.html | 3 - docs/_includes/category-list.html | 26 - docs/_includes/comment.html | 22 - docs/_includes/comments-providers/custom.html | 3 - .../comments-providers/discourse.html | 13 - docs/_includes/comments-providers/disqus.html | 22 - .../comments-providers/facebook.html | 8 - .../comments-providers/google-plus.html | 2 - .../_includes/comments-providers/scripts.html | 16 - .../comments-providers/staticman.html | 42 - docs/_includes/comments.html | 95 - docs/_includes/demo.html | 13 + docs/_includes/feature_row | 50 - docs/_includes/figure | 12 - docs/_includes/files/docker-compose.yml | 37 + docs/_includes/footer.html | 42 +- docs/_includes/footer/custom.html | 3 - docs/_includes/gallery | 47 - docs/_includes/group-by-array | 47 - docs/_includes/head.html | 44 +- docs/_includes/head/custom.html | 5 - docs/_includes/header.html | 12 + docs/_includes/images/hamburger.svg | 5 + docs/_includes/images/logo.svg | 41 + docs/_includes/images/moz-logo-bw-rgb.svg | 22 + docs/_includes/masthead.html | 21 - docs/_includes/nav_list | 47 - docs/_includes/page__hero.html | 53 - docs/_includes/page__hero_video.html | 4 - docs/_includes/page__taxonomy.html | 7 - docs/_includes/paginator.html | 69 - docs/_includes/post_pagination.html | 14 - docs/_includes/read-time.html | 15 - docs/_includes/scripts.html | 4 - docs/_includes/seo.html | 147 - docs/_includes/sidebar.html | 49 +- docs/_includes/social-share.html | 13 - docs/_includes/tag-list.html | 26 - docs/_includes/toc | 7 - docs/_includes/toc.html | 7 + docs/_includes/video | 11 - docs/_layouts/archive-taxonomy.html | 15 - docs/_layouts/archive.html | 26 - docs/_layouts/compress.html | 10 - docs/_layouts/default.html | 42 +- docs/_layouts/doc.html | 11 + docs/_layouts/home.html | 11 - docs/_layouts/single.html | 74 - docs/_layouts/splash.html | 22 - docs/_sass/_hljs.scss | 99 + docs/_sass/_mixins.scss | 22 + docs/_sass/_variables.scss | 21 + docs/_sass/minimal-mistakes.scss | 40 - docs/_sass/minimal-mistakes/_animations.scss | 21 - docs/_sass/minimal-mistakes/_archive.scss | 238 -- docs/_sass/minimal-mistakes/_base.scss | 315 -- docs/_sass/minimal-mistakes/_buttons.scss | 153 - docs/_sass/minimal-mistakes/_footer.scss | 80 - docs/_sass/minimal-mistakes/_forms.scss | 391 --- docs/_sass/minimal-mistakes/_masthead.scss | 77 - docs/_sass/minimal-mistakes/_mixins.scss | 53 - docs/_sass/minimal-mistakes/_navigation.scss | 551 ---- docs/_sass/minimal-mistakes/_notices.scss | 99 - docs/_sass/minimal-mistakes/_page.scss | 408 --- docs/_sass/minimal-mistakes/_print.scss | 238 -- docs/_sass/minimal-mistakes/_reset.scss | 187 -- docs/_sass/minimal-mistakes/_sidebar.scss | 237 -- docs/_sass/minimal-mistakes/_syntax.scss | 146 - docs/_sass/minimal-mistakes/_tables.scss | 38 - docs/_sass/minimal-mistakes/_utilities.scss | 518 ---- docs/_sass/minimal-mistakes/_variables.scss | 129 - .../vendor/breakpoint/_breakpoint.scss | 114 - .../vendor/breakpoint/_context.scss | 95 - .../vendor/breakpoint/_helpers.scss | 151 - .../vendor/breakpoint/_legacy-settings.scss | 50 - .../vendor/breakpoint/_no-query.scss | 15 - .../vendor/breakpoint/_parsers.scss | 215 -- .../vendor/breakpoint/_respond-to.scss | 82 - .../vendor/breakpoint/_settings.scss | 71 - .../vendor/breakpoint/parsers/_double.scss | 33 - .../vendor/breakpoint/parsers/_query.scss | 82 - .../breakpoint/parsers/_resolution.scss | 31 - .../vendor/breakpoint/parsers/_single.scss | 26 - .../vendor/breakpoint/parsers/_triple.scss | 36 - .../parsers/double/_default-pair.scss | 21 - .../breakpoint/parsers/double/_default.scss | 22 - .../parsers/double/_double-string.scss | 22 - .../parsers/resolution/_resolution.scss | 60 - .../breakpoint/parsers/single/_default.scss | 13 - .../breakpoint/parsers/triple/_default.scss | 18 - .../vendor/font-awesome/_animated.scss | 34 - .../vendor/font-awesome/_bordered-pulled.scss | 25 - .../vendor/font-awesome/_core.scss | 12 - .../vendor/font-awesome/_fixed-width.scss | 6 - .../vendor/font-awesome/_font-awesome.scss | 18 - .../vendor/font-awesome/_icons.scss | 789 ----- .../vendor/font-awesome/_larger.scss | 13 - .../vendor/font-awesome/_list.scss | 19 - .../vendor/font-awesome/_mixins.scss | 60 - .../vendor/font-awesome/_path.scss | 15 - .../vendor/font-awesome/_rotated-flipped.scss | 20 - .../vendor/font-awesome/_screen-reader.scss | 5 - .../vendor/font-awesome/_stacked.scss | 20 - .../vendor/font-awesome/_variables.scss | 800 ----- .../magnific-popup/_magnific-popup.scss | 649 ---- .../vendor/magnific-popup/_settings.scss | 46 - .../minimal-mistakes/vendor/susy/_su.scss | 4 - .../minimal-mistakes/vendor/susy/_susy.scss | 4 - .../vendor/susy/_susyone.scss | 4 - .../vendor/susy/susy/_su.scss | 7 - .../vendor/susy/susy/language/_susy.scss | 24 - .../vendor/susy/susy/language/_susyone.scss | 13 - .../susy/susy/language/susy/_background.scss | 385 --- .../susy/susy/language/susy/_bleed.scss | 200 -- .../susy/susy/language/susy/_box-sizing.scss | 47 - .../language/susy/_breakpoint-plugin.scss | 185 -- .../susy/susy/language/susy/_container.scss | 81 - .../susy/susy/language/susy/_context.scss | 36 - .../susy/susy/language/susy/_gallery.scss | 94 - .../susy/susy/language/susy/_grids.scss | 64 - .../susy/susy/language/susy/_gutters.scss | 154 - .../susy/susy/language/susy/_isolate.scss | 77 - .../susy/susy/language/susy/_margins.scss | 94 - .../susy/susy/language/susy/_padding.scss | 74 - .../vendor/susy/susy/language/susy/_rows.scss | 138 - .../susy/susy/language/susy/_settings.scss | 216 -- .../vendor/susy/susy/language/susy/_span.scss | 163 - .../susy/susy/language/susy/_validation.scss | 16 - .../susy/language/susyone/_background.scss | 18 - .../susy/language/susyone/_functions.scss | 377 --- .../susy/susy/language/susyone/_grid.scss | 312 -- .../susy/language/susyone/_isolation.scss | 51 - .../susy/susy/language/susyone/_margin.scss | 93 - .../susy/susy/language/susyone/_media.scss | 105 - .../susy/susy/language/susyone/_padding.scss | 92 - .../susy/susy/language/susyone/_settings.scss | 60 - .../vendor/susy/susy/output/_float.scss | 9 - .../vendor/susy/susy/output/_shared.scss | 15 - .../vendor/susy/susy/output/_support.scss | 9 - .../susy/susy/output/float/_container.scss | 16 - .../vendor/susy/susy/output/float/_end.scss | 40 - .../susy/susy/output/float/_isolate.scss | 22 - .../vendor/susy/susy/output/float/_span.scss | 35 - .../susy/susy/output/shared/_background.scss | 26 - .../susy/susy/output/shared/_container.scss | 21 - .../susy/susy/output/shared/_direction.scss | 42 - .../susy/susy/output/shared/_inspect.scss | 25 - .../susy/susy/output/shared/_margins.scss | 23 - .../susy/susy/output/shared/_output.scss | 14 - .../susy/susy/output/shared/_padding.scss | 23 - .../susy/susy/output/support/_background.scss | 58 - .../susy/susy/output/support/_box-sizing.scss | 19 - .../susy/susy/output/support/_clearfix.scss | 18 - .../susy/susy/output/support/_prefix.scss | 19 - .../vendor/susy/susy/output/support/_rem.scss | 22 - .../susy/susy/output/support/_support.scss | 85 - .../vendor/susy/susy/su/_grid.scss | 103 - .../vendor/susy/susy/su/_settings.scss | 73 - .../vendor/susy/susy/su/_utilities.scss | 111 - .../vendor/susy/susy/su/_validation.scss | 57 - docs/_sass/talk.scss | 408 +++ docs/assets/css/{main.scss => main.min.scss} | 4 +- docs/assets/fonts/FontAwesome.otf | Bin 134808 -> 0 bytes docs/assets/fonts/fontawesome-webfont.eot | Bin 165742 -> 0 bytes docs/assets/fonts/fontawesome-webfont.svg | 2671 ----------------- docs/assets/fonts/fontawesome-webfont.ttf | Bin 165548 -> 0 bytes docs/assets/fonts/fontawesome-webfont.woff | Bin 98024 -> 0 bytes docs/assets/fonts/fontawesome-webfont.woff2 | Bin 77160 -> 0 bytes docs/assets/js/_main.js | 72 - docs/assets/js/highlight.min.js | 2 + docs/assets/js/main.js | 143 + docs/assets/js/main.min.js | 13 - docs/assets/js/plugins/jquery.fitvids.js | 82 - .../js/plugins/jquery.greedy-navigation.js | 78 - .../js/plugins/jquery.magnific-popup.js | 2049 ------------- .../js/plugins/jquery.smooth-scroll.min.js | 8 - .../js/vendor/jquery/jquery-1.12.4.min.js | 5 - docs/banner.js | 21 - docs/index.md | 65 - docs/package.json | 34 - docs/swagger.yaml | 504 ---- 234 files changed, 2050 insertions(+), 22791 deletions(-) rename docs/_docs/05-03-code-of-conduct.md => CODE_OF_CONDUCT.md (95%) rename docs/_docs/05-02-contributors-guide.md => CONTRIBUTING.md (85%) create mode 100644 docs/404.html mode change 100755 => 100644 docs/Gemfile delete mode 100755 docs/LICENSE.txt delete mode 100755 docs/Rakefile mode change 100755 => 100644 docs/_config.yml create mode 100644 docs/_data/badges.yaml create mode 100644 docs/_data/nav.yaml delete mode 100755 docs/_data/navigation.yml delete mode 100755 docs/_data/ui-text.yml delete mode 100644 docs/_docs/00-01-faq.md delete mode 100644 docs/_docs/01-01-install.md delete mode 100644 docs/_docs/01-02-install-docker.md delete mode 100644 docs/_docs/01-03-install-source.md delete mode 100644 docs/_docs/01-04-install-setup.md delete mode 100644 docs/_docs/01-05-install-microservices.md delete mode 100644 docs/_docs/01-06-install-troubleshooting.md delete mode 100644 docs/_docs/02-01-configuration.md delete mode 100644 docs/_docs/02-02-secrets.md delete mode 100644 docs/_docs/02-03-plugins.md delete mode 100644 docs/_docs/02-04-migrations.md delete mode 100644 docs/_docs/02-05-persistence.md delete mode 100644 docs/_docs/03-01-architecture.md delete mode 100644 docs/_docs/03-02-architecture-tags.md delete mode 100644 docs/_docs/03-03-architecture-metadata.md delete mode 100644 docs/_docs/03-04-architecture-cli.md delete mode 100644 docs/_docs/03-05-client-architecture.md delete mode 100644 docs/_docs/04-02-plugins-quickstart.md delete mode 100644 docs/_docs/04-03-plugins-client.md delete mode 100644 docs/_docs/04-04-plugins-server.md delete mode 100644 docs/_docs/04-05-plugins-experimental.md delete mode 100644 docs/_docs/05-01-development-tools.md delete mode 100644 docs/_docs/05-04-rest-api.md create mode 100644 docs/_docs/installation-from-docker.md create mode 100644 docs/_docs/installation-from-source.md create mode 100644 docs/_docs/installation-talk-quickstart.md rename docs/_docs/{04-01-plugins.md => plugins-overview.md} (69%) create mode 100644 docs/_docs/running-advanced-configuration.md create mode 100644 docs/_docs/running-required-configuration.md delete mode 100755 docs/_includes/analytics-providers/custom.html delete mode 100755 docs/_includes/analytics-providers/google-universal.html delete mode 100755 docs/_includes/analytics-providers/google.html delete mode 100755 docs/_includes/analytics.html delete mode 100755 docs/_includes/archive-single.html delete mode 100755 docs/_includes/author-profile-custom-links.html delete mode 100755 docs/_includes/author-profile.html create mode 100644 docs/_includes/badges.html delete mode 100755 docs/_includes/base_path delete mode 100755 docs/_includes/breadcrumbs.html delete mode 100755 docs/_includes/browser-upgrade.html delete mode 100755 docs/_includes/category-list.html delete mode 100755 docs/_includes/comment.html delete mode 100755 docs/_includes/comments-providers/custom.html delete mode 100755 docs/_includes/comments-providers/discourse.html delete mode 100755 docs/_includes/comments-providers/disqus.html delete mode 100755 docs/_includes/comments-providers/facebook.html delete mode 100755 docs/_includes/comments-providers/google-plus.html delete mode 100755 docs/_includes/comments-providers/scripts.html delete mode 100755 docs/_includes/comments-providers/staticman.html delete mode 100755 docs/_includes/comments.html create mode 100644 docs/_includes/demo.html delete mode 100755 docs/_includes/feature_row delete mode 100755 docs/_includes/figure create mode 100644 docs/_includes/files/docker-compose.yml mode change 100755 => 100644 docs/_includes/footer.html delete mode 100755 docs/_includes/footer/custom.html delete mode 100755 docs/_includes/gallery delete mode 100755 docs/_includes/group-by-array mode change 100755 => 100644 docs/_includes/head.html delete mode 100755 docs/_includes/head/custom.html create mode 100644 docs/_includes/header.html create mode 100644 docs/_includes/images/hamburger.svg create mode 100644 docs/_includes/images/logo.svg create mode 100644 docs/_includes/images/moz-logo-bw-rgb.svg delete mode 100755 docs/_includes/masthead.html delete mode 100755 docs/_includes/nav_list delete mode 100755 docs/_includes/page__hero.html delete mode 100755 docs/_includes/page__hero_video.html delete mode 100755 docs/_includes/page__taxonomy.html delete mode 100755 docs/_includes/paginator.html delete mode 100755 docs/_includes/post_pagination.html delete mode 100755 docs/_includes/read-time.html delete mode 100755 docs/_includes/scripts.html delete mode 100755 docs/_includes/seo.html mode change 100755 => 100644 docs/_includes/sidebar.html delete mode 100755 docs/_includes/social-share.html delete mode 100755 docs/_includes/tag-list.html delete mode 100755 docs/_includes/toc create mode 100644 docs/_includes/toc.html delete mode 100755 docs/_includes/video delete mode 100755 docs/_layouts/archive-taxonomy.html delete mode 100755 docs/_layouts/archive.html delete mode 100755 docs/_layouts/compress.html mode change 100755 => 100644 docs/_layouts/default.html create mode 100644 docs/_layouts/doc.html delete mode 100755 docs/_layouts/home.html delete mode 100755 docs/_layouts/single.html delete mode 100755 docs/_layouts/splash.html create mode 100644 docs/_sass/_hljs.scss create mode 100644 docs/_sass/_mixins.scss create mode 100644 docs/_sass/_variables.scss delete mode 100755 docs/_sass/minimal-mistakes.scss delete mode 100755 docs/_sass/minimal-mistakes/_animations.scss delete mode 100755 docs/_sass/minimal-mistakes/_archive.scss delete mode 100755 docs/_sass/minimal-mistakes/_base.scss delete mode 100755 docs/_sass/minimal-mistakes/_buttons.scss delete mode 100755 docs/_sass/minimal-mistakes/_footer.scss delete mode 100755 docs/_sass/minimal-mistakes/_forms.scss delete mode 100755 docs/_sass/minimal-mistakes/_masthead.scss delete mode 100755 docs/_sass/minimal-mistakes/_mixins.scss delete mode 100755 docs/_sass/minimal-mistakes/_navigation.scss delete mode 100755 docs/_sass/minimal-mistakes/_notices.scss delete mode 100755 docs/_sass/minimal-mistakes/_page.scss delete mode 100755 docs/_sass/minimal-mistakes/_print.scss delete mode 100755 docs/_sass/minimal-mistakes/_reset.scss delete mode 100755 docs/_sass/minimal-mistakes/_sidebar.scss delete mode 100755 docs/_sass/minimal-mistakes/_syntax.scss delete mode 100755 docs/_sass/minimal-mistakes/_tables.scss delete mode 100755 docs/_sass/minimal-mistakes/_utilities.scss delete mode 100755 docs/_sass/minimal-mistakes/_variables.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/breakpoint/_breakpoint.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/breakpoint/_context.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/breakpoint/_helpers.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/breakpoint/_legacy-settings.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/breakpoint/_no-query.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/breakpoint/_parsers.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/breakpoint/_respond-to.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/breakpoint/_settings.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/breakpoint/parsers/_double.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/breakpoint/parsers/_query.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/breakpoint/parsers/_resolution.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/breakpoint/parsers/_single.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/breakpoint/parsers/_triple.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/breakpoint/parsers/double/_default-pair.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/breakpoint/parsers/double/_default.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/breakpoint/parsers/double/_double-string.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/breakpoint/parsers/resolution/_resolution.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/breakpoint/parsers/single/_default.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/breakpoint/parsers/triple/_default.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/font-awesome/_animated.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/font-awesome/_bordered-pulled.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/font-awesome/_core.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/font-awesome/_fixed-width.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/font-awesome/_font-awesome.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/font-awesome/_icons.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/font-awesome/_larger.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/font-awesome/_list.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/font-awesome/_mixins.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/font-awesome/_path.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/font-awesome/_rotated-flipped.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/font-awesome/_screen-reader.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/font-awesome/_stacked.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/font-awesome/_variables.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/magnific-popup/_magnific-popup.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/magnific-popup/_settings.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/_su.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/_susy.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/_susyone.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/_su.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/language/_susy.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/language/_susyone.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/language/susy/_background.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/language/susy/_bleed.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/language/susy/_box-sizing.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/language/susy/_breakpoint-plugin.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/language/susy/_container.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/language/susy/_context.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/language/susy/_gallery.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/language/susy/_grids.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/language/susy/_gutters.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/language/susy/_isolate.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/language/susy/_margins.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/language/susy/_padding.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/language/susy/_rows.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/language/susy/_settings.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/language/susy/_span.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/language/susy/_validation.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/language/susyone/_background.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/language/susyone/_functions.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/language/susyone/_grid.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/language/susyone/_isolation.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/language/susyone/_margin.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/language/susyone/_media.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/language/susyone/_padding.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/language/susyone/_settings.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/output/_float.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/output/_shared.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/output/_support.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/output/float/_container.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/output/float/_end.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/output/float/_isolate.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/output/float/_span.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/output/shared/_background.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/output/shared/_container.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/output/shared/_direction.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/output/shared/_inspect.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/output/shared/_margins.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/output/shared/_output.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/output/shared/_padding.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/output/support/_background.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/output/support/_box-sizing.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/output/support/_clearfix.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/output/support/_prefix.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/output/support/_rem.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/output/support/_support.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/su/_grid.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/su/_settings.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/su/_utilities.scss delete mode 100755 docs/_sass/minimal-mistakes/vendor/susy/susy/su/_validation.scss create mode 100644 docs/_sass/talk.scss rename docs/assets/css/{main.scss => main.min.scss} (62%) mode change 100755 => 100644 delete mode 100755 docs/assets/fonts/FontAwesome.otf delete mode 100755 docs/assets/fonts/fontawesome-webfont.eot delete mode 100755 docs/assets/fonts/fontawesome-webfont.svg delete mode 100755 docs/assets/fonts/fontawesome-webfont.ttf delete mode 100755 docs/assets/fonts/fontawesome-webfont.woff delete mode 100755 docs/assets/fonts/fontawesome-webfont.woff2 delete mode 100755 docs/assets/js/_main.js create mode 100644 docs/assets/js/highlight.min.js create mode 100644 docs/assets/js/main.js delete mode 100755 docs/assets/js/main.min.js delete mode 100755 docs/assets/js/plugins/jquery.fitvids.js delete mode 100755 docs/assets/js/plugins/jquery.greedy-navigation.js delete mode 100755 docs/assets/js/plugins/jquery.magnific-popup.js delete mode 100755 docs/assets/js/plugins/jquery.smooth-scroll.min.js delete mode 100755 docs/assets/js/vendor/jquery/jquery-1.12.4.min.js delete mode 100755 docs/banner.js delete mode 100755 docs/index.md delete mode 100755 docs/package.json delete mode 100644 docs/swagger.yaml diff --git a/docs/_docs/05-03-code-of-conduct.md b/CODE_OF_CONDUCT.md similarity index 95% rename from docs/_docs/05-03-code-of-conduct.md rename to CODE_OF_CONDUCT.md index c223fe4a0..449ef585b 100644 --- a/docs/_docs/05-03-code-of-conduct.md +++ b/CODE_OF_CONDUCT.md @@ -1,7 +1,4 @@ ---- -title: Contributor Covenant Code of Conduct -permalink: /docs/development/code-of-conduct/ ---- +# Contributor Covenant Code of Conduct ## Our Pledge @@ -46,7 +43,7 @@ Other inappropriate behavior: * Impersonation of someone else * Violating someone’s privacy -If you feel that someone has harassed you or otherwise treated you or someone else inappropriately, please alert the project lead at [andrewl@mozillafoundation.org](mailto:andrewl@mozillafoundation.org). +If you feel that someone has harassed you or otherwise treated you or someone else inappropriately, please alert the project lead at [andrewl@mozillafoundation.org](mailto:andrewl@mozillafoundation.org). ## Our Responsibilities @@ -71,11 +68,11 @@ If you’re too frustrated to have a direct conversation, there are a number of * Contact the project lead, Andrew Losowsky, [andrewl@mozillafoundation.org](mailto:andrewl@mozillafoundation.org), or the technical lead. We will work with you to help you figure out how to ensure that any conflict doesn’t interfere with your work, in confidence if you would prefer. -* Talk to Chris Lawrence. Chris oversees the project. He can be contacted at [clawrence@mozillafoundation.org](mailto:clawrence@mozillafoundation.org). +* Talk to Chris Lawrence. Chris oversees the project. He can be contacted at [clawrence@mozillafoundation.org](mailto:clawrence@mozillafoundation.org). If you feel you have been unfairly accused of violating this code of conduct, you should contact Chris with a concise description of your grievance. ## Conclusion We welcome your feedback on this and every other aspect of what we do as The Coral Project, and we thank you for working with us to make it a safe, enjoyable, and friendly experience for everyone involved in the project and what we do. -Above text is licensed CC BY-SA 4.0, adapted from the SRCCON code of conduct, FreeBSD’s code of conduct, Vox Media’s product team code of conduct, Medium’s code of conduct, as well as adapted from the Contributor Covenant. +Above text is licensed CC BY-SA 4.0, adapted from the SRCCON code of conduct, FreeBSD’s code of conduct, Vox Media’s product team code of conduct, Medium’s code of conduct, as well as adapted from the Contributor Covenant. \ No newline at end of file diff --git a/docs/_docs/05-02-contributors-guide.md b/CONTRIBUTING.md similarity index 85% rename from docs/_docs/05-02-contributors-guide.md rename to CONTRIBUTING.md index 74ebbe071..33324ea5a 100644 --- a/docs/_docs/05-02-contributors-guide.md +++ b/CONTRIBUTING.md @@ -1,13 +1,10 @@ ---- -title: Contributor's Guide -permalink: /docs/development/contributing/ ---- +# Contributor's Guide Welcome! We are very excited that you are interested in contributing to Talk. This document is a companion to help you approach contributing. If it does not do so, please [let us know how we can improve it](https://github.com/coralproject/talk/issues)! -By contributing to this project you agree to the [Code of Conduct](https://coralproject.net/code-of-conduct). +By contributing to this project you agree to the [Code of Conduct](CODE_OF_CONDUCT.md). ## What should I Contribute? @@ -33,7 +30,7 @@ Please file issues if: ### What should I include? -Coral has adopted an iterative, agile development philosophy. All contributions that make it into the Talk repo should start with a story or this form: +Coral has adopted an iterative, agile development philosophy. All contributions that make it into the Talk repository should start with a story or this form: > As a [type of person] I'd like to be able to [do something] so that I can [get some result]. @@ -56,15 +53,24 @@ We are looking for _documentarians_ to: * create new / missing sections, and * take the lead in making sections, or the over all structure better. -Information about how to update docs can be found in our [FAQ]({{ "/docs/faq" | absolute_url }}#how-do-i-contribute-to-these-docs). +Our documentation is stored in markdown files in the [docs](docs) directory. We +use Jekyll to provide our docs. To preview: + +```shell +cd docs +bundle install +bundle exec jekyll serve +``` + +Then visit http://127.0.0.1:4000/talk/. If you'd like to discuss a contribution, please [file an issue](https://github.com/coralproject/talk/issues) describing the changes you would like to see. ## Contributing Translations -Talk's tranlations are stored in `.yml` files [here](https://github.com/coralproject/talk/tree/master/locales). +Talk's translations are stored in `.yml` files [here](https://github.com/coralproject/talk/tree/master/locales). -Translations can be submitted via pull request. If you do not use github, you can use 'en.yml' as a template and [email](https://coralproject.net/contact) the translations to us. We can import it into the repo. +Translations can be submitted via pull request. If you do not use github, you can use 'en.yml' as a template and [email](https://coralproject.net/contact) the translations to us. We can import it into the repository. ## I want to contribute but I'm not sure what to do! @@ -84,4 +90,4 @@ Have a favorite analytics engine? Data science service? CMS? Auth platform? Depl ### Favorite Features? -Do you have a favorite feature of an existing platform that's not yet been done in Talk? Sounds like Talk needs that feature. +Do you have a favorite feature of an existing platform that's not yet been done in Talk? Sounds like Talk needs that feature. \ No newline at end of file diff --git a/README.md b/README.md index 57562fc1a..919093750 100644 --- a/README.md +++ b/README.md @@ -1,29 +1,19 @@ # Talk [![CircleCI](https://circleci.com/gh/coralproject/talk.svg?style=svg)](https://circleci.com/gh/coralproject/talk) [![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://dashboard.heroku.com/new?template=https%3A%2F%2Fgithub.com%2Fcoralproject%2Ftalk&env[TALK_FACEBOOK_APP_ID]=ignore&env[TALK_FACEBOOK_APP_SECRET]=ignore) -Online comments are broken. Our open-source Talk tool rethinks how moderation, comment display, and conversation function, creating the opportunity for safer, smarter discussions around your work. [Read more about Talk here.](https://coralproject.net/products/talk.html) +Online comments are broken. Our open-source Talk tool rethinks how moderation, comment display, and conversation function, creating the opportunity for safer, smarter discussions around your work. [Read more about Talk here](https://coralproject.net/products/talk.html). -Third party licenses are available via the `/client/3rdpartylicenses.txt` -endpoint when the server is running with built assets. +## Documentation -## Try Talk! +Developer Documentation & Setup Guides https://coralproject.github.io/talk/. -- Developer Documentation & Setup Guides: https://coralproject.github.io/talk/ (includes Installation Guide, Quickstart, Plugin Guide, API Docs, and more) - -## Roadmap and Release Schedule - -- Talk Roadmap: https://www.pivotaltracker.com/n/projects/1863625 - - -## Learn More about Coral +## Relevant Links +- Blog: https://blog.coralproject.net/ - Community Forums: https://community.coralproject.net/ - -- Website: https://coralproject.net - -- Blog: https://blog.coralproject.net - - Community Guides for Journalism: https://guides.coralproject.net/ +- Project: https://coralproject.net/ +- Roadmap: https://www.pivotaltracker.com/n/projects/1863625 ## License diff --git a/docs/.gitignore b/docs/.gitignore index b33f7679f..45c150536 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -1,6 +1,3 @@ -_site/ -.sass-cache/ +_site +.sass-cache .jekyll-metadata -_pdf -.idea/ -.DS_Store diff --git a/docs/404.html b/docs/404.html new file mode 100644 index 000000000..4b8e30d9d --- /dev/null +++ b/docs/404.html @@ -0,0 +1,22 @@ +--- +layout: doc +--- + + + +
+

404

+ +

Page not found :(

+

The requested page could not be found. Try searching above for your page.

+
diff --git a/docs/Gemfile b/docs/Gemfile old mode 100755 new mode 100644 index 0dee02654..bdc644fef --- a/docs/Gemfile +++ b/docs/Gemfile @@ -1,11 +1,24 @@ source "https://rubygems.org" -gem "github-pages", group: :jekyll_plugins +# Hello! This is where you manage which Jekyll version is used to run. +# When you want to use a different version, change it below, save the +# file and run `bundle install`. Run Jekyll with `bundle exec`, like so: +# +# bundle exec jekyll serve +# +# This will help ensure the proper Jekyll version is running. +# Happy Jekylling! +gem "jekyll", "3.5.2" +# If you want to use GitHub Pages, remove the "gem "jekyll"" above and +# uncomment the line below. To upgrade, run `bundle update github-pages`. +# gem "github-pages", group: :jekyll_plugins + +# If you have any plugins, put them here! group :jekyll_plugins do - gem "jekyll-paginate" - gem "jekyll-sitemap" - gem "jekyll-gist" - gem "jekyll-feed" - gem "jemoji" -end \ No newline at end of file + gem "jekyll-seo-tag", "~> 2.1" +end + +# Windows does not include zoneinfo files, so bundle the tzinfo-data gem +gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] + diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index adda86bbd..62b708a5d 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -1,176 +1,45 @@ GEM remote: https://rubygems.org/ specs: - activesupport (4.2.8) - i18n (~> 0.7) - minitest (~> 5.1) - thread_safe (~> 0.3, >= 0.3.4) - tzinfo (~> 1.1) - addressable (2.5.1) - public_suffix (~> 2.0, >= 2.0.2) - coffee-script (2.4.1) - coffee-script-source - execjs - coffee-script-source (1.11.1) + addressable (2.5.2) + public_suffix (>= 2.0.2, < 4.0) colorator (1.1.0) - ethon (0.10.1) - ffi (>= 1.3.0) + cssminify2 (2.0.1) execjs (2.7.0) - faraday (0.12.1) - multipart-post (>= 1.2, < 3) ffi (1.9.18) forwardable-extended (2.6.0) - gemoji (3.0.0) - github-pages (145) - activesupport (= 4.2.8) - github-pages-health-check (= 1.3.4) - jekyll (= 3.4.5) - jekyll-avatar (= 0.4.2) - jekyll-coffeescript (= 1.0.1) - jekyll-default-layout (= 0.1.4) - jekyll-feed (= 0.9.2) - jekyll-gist (= 1.4.0) - jekyll-github-metadata (= 2.5.1) - jekyll-mentions (= 1.2.0) - jekyll-optional-front-matter (= 0.2.0) - jekyll-paginate (= 1.1.0) - jekyll-readme-index (= 0.1.0) - jekyll-redirect-from (= 0.12.1) - jekyll-relative-links (= 0.4.1) - jekyll-sass-converter (= 1.5.0) - jekyll-seo-tag (= 2.2.3) - jekyll-sitemap (= 1.0.0) - jekyll-swiss (= 0.4.0) - jekyll-theme-architect (= 0.0.4) - jekyll-theme-cayman (= 0.0.4) - jekyll-theme-dinky (= 0.0.4) - jekyll-theme-hacker (= 0.0.4) - jekyll-theme-leap-day (= 0.0.4) - jekyll-theme-merlot (= 0.0.4) - jekyll-theme-midnight (= 0.0.4) - jekyll-theme-minimal (= 0.0.4) - jekyll-theme-modernist (= 0.0.4) - jekyll-theme-primer (= 0.3.1) - jekyll-theme-slate (= 0.0.4) - jekyll-theme-tactile (= 0.0.4) - jekyll-theme-time-machine (= 0.0.4) - jekyll-titles-from-headings (= 0.2.0) - jemoji (= 0.8.0) - kramdown (= 1.13.2) - liquid (= 3.0.6) - listen (= 3.0.6) - mercenary (~> 0.3) - minima (= 2.1.1) - rouge (= 1.11.1) - terminal-table (~> 1.4) - github-pages-health-check (1.3.4) - addressable (~> 2.3) - net-dns (~> 0.8) - octokit (~> 4.0) - public_suffix (~> 2.0) - typhoeus (~> 0.7) - html-pipeline (2.6.0) - activesupport (>= 2) - nokogiri (>= 1.4) - i18n (0.8.6) - jekyll (3.4.5) + htmlcompressor (0.3.1) + jekyll (3.5.2) addressable (~> 2.4) colorator (~> 1.0) jekyll-sass-converter (~> 1.0) jekyll-watch (~> 1.1) kramdown (~> 1.3) - liquid (~> 3.0) + liquid (~> 4.0) mercenary (~> 0.3.3) pathutil (~> 0.9) rouge (~> 1.7) safe_yaml (~> 1.0) - jekyll-avatar (0.4.2) - jekyll (~> 3.0) - jekyll-coffeescript (1.0.1) - coffee-script (~> 2.2) - jekyll-default-layout (0.1.4) - jekyll (~> 3.0) - jekyll-feed (0.9.2) - jekyll (~> 3.3) - jekyll-gist (1.4.0) - octokit (~> 4.2) - jekyll-github-metadata (2.5.1) - jekyll (~> 3.1) - octokit (~> 4.0, != 4.4.0) - jekyll-mentions (1.2.0) - activesupport (~> 4.0) - html-pipeline (~> 2.3) - jekyll (~> 3.0) - jekyll-optional-front-matter (0.2.0) - jekyll (~> 3.0) - jekyll-paginate (1.1.0) - jekyll-readme-index (0.1.0) - jekyll (~> 3.0) - jekyll-redirect-from (0.12.1) - jekyll (~> 3.3) - jekyll-relative-links (0.4.1) - jekyll (~> 3.3) + jekyll-minifier (0.1.4) + cssminify2 (~> 2.0) + htmlcompressor (~> 0.3) + jekyll (~> 3.5) + uglifier (~> 3.2) jekyll-sass-converter (1.5.0) sass (~> 3.4) - jekyll-seo-tag (2.2.3) - jekyll (~> 3.3) - jekyll-sitemap (1.0.0) - jekyll (~> 3.3) - jekyll-swiss (0.4.0) - jekyll-theme-architect (0.0.4) - jekyll (~> 3.3) - jekyll-theme-cayman (0.0.4) - jekyll (~> 3.3) - jekyll-theme-dinky (0.0.4) - jekyll (~> 3.3) - jekyll-theme-hacker (0.0.4) - jekyll (~> 3.3) - jekyll-theme-leap-day (0.0.4) - jekyll (~> 3.3) - jekyll-theme-merlot (0.0.4) - jekyll (~> 3.3) - jekyll-theme-midnight (0.0.4) - jekyll (~> 3.3) - jekyll-theme-minimal (0.0.4) - jekyll (~> 3.3) - jekyll-theme-modernist (0.0.4) - jekyll (~> 3.3) - jekyll-theme-primer (0.3.1) - jekyll (~> 3.3) - jekyll-theme-slate (0.0.4) - jekyll (~> 3.3) - jekyll-theme-tactile (0.0.4) - jekyll (~> 3.3) - jekyll-theme-time-machine (0.0.4) - jekyll (~> 3.3) - jekyll-titles-from-headings (0.2.0) + jekyll-seo-tag (2.3.0) jekyll (~> 3.3) jekyll-watch (1.5.0) listen (~> 3.0, < 3.1) - jemoji (0.8.0) - activesupport (~> 4.0) - gemoji (~> 3.0) - html-pipeline (~> 2.2) - jekyll (>= 3.0) - kramdown (1.13.2) - liquid (3.0.6) - listen (3.0.6) - rb-fsevent (>= 0.9.3) - rb-inotify (>= 0.9.7) + kramdown (1.15.0) + liquid (4.0.0) + listen (3.0.8) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) mercenary (0.3.6) - mini_portile2 (2.2.0) - minima (2.1.1) - jekyll (~> 3.3) - minitest (5.10.2) - multipart-post (2.0.0) - net-dns (0.8.0) - nokogiri (1.8.0) - mini_portile2 (~> 2.2.0) - octokit (4.7.0) - sawyer (~> 0.8.0, >= 0.5.3) pathutil (0.14.0) forwardable-extended (~> 2.6) - public_suffix (2.0.5) + public_suffix (3.0.0) rb-fsevent (0.10.2) rb-inotify (0.9.10) ffi (>= 0.5.0, < 2) @@ -181,28 +50,17 @@ GEM sass-listen (4.0.0) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) - sawyer (0.8.1) - addressable (>= 2.3.5, < 2.6) - faraday (~> 0.8, < 1.0) - terminal-table (1.8.0) - unicode-display_width (~> 1.1, >= 1.1.1) - thread_safe (0.3.6) - typhoeus (0.8.0) - ethon (>= 0.8.0) - tzinfo (1.2.3) - thread_safe (~> 0.1) - unicode-display_width (1.3.0) + uglifier (3.2.0) + execjs (>= 0.3.0, < 3) PLATFORMS ruby DEPENDENCIES - github-pages - jekyll-feed - jekyll-gist - jekyll-paginate - jekyll-sitemap - jemoji + jekyll (= 3.5.2) + jekyll-minifier (~> 0.1.4) + jekyll-seo-tag (~> 2.1) + tzinfo-data BUNDLED WITH - 1.15.2 + 1.15.4 diff --git a/docs/LICENSE.txt b/docs/LICENSE.txt deleted file mode 100755 index b7cc9a0dc..000000000 --- a/docs/LICENSE.txt +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 Michael Rose - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/docs/Rakefile b/docs/Rakefile deleted file mode 100755 index e50d89f84..000000000 --- a/docs/Rakefile +++ /dev/null @@ -1,75 +0,0 @@ -require "bundler/gem_tasks" -require "jekyll" -require "listen" - -def listen_ignore_paths(base, options) - [ - /_config\.ya?ml/, - /_site/, - /\.jekyll-metadata/ - ] -end - -def listen_handler(base, options) - site = Jekyll::Site.new(options) - Jekyll::Command.process_site(site) - proc do |modified, added, removed| - t = Time.now - c = modified + added + removed - n = c.length - relative_paths = c.map{ |p| Pathname.new(p).relative_path_from(base).to_s } - print Jekyll.logger.message("Regenerating:", "#{relative_paths.join(", ")} changed... ") - begin - Jekyll::Command.process_site(site) - puts "regenerated in #{Time.now - t} seconds." - rescue => e - puts "error:" - Jekyll.logger.warn "Error:", e.message - Jekyll.logger.warn "Error:", "Run jekyll build --trace for more information." - end - end -end - -task :preview do - base = Pathname.new('.').expand_path - options = { - "source" => base.join('test').to_s, - "destination" => base.join('test/_site').to_s, - "force_polling" => false, - "serving" => true, - "theme" => "minimal-mistakes-jekyll" - } - - options = Jekyll.configuration(options) - - ENV["LISTEN_GEM_DEBUGGING"] = "1" - listener = Listen.to( - base.join("_includes"), - base.join("_layouts"), - base.join("_sass"), - base.join("assets"), - options["source"], - :ignore => listen_ignore_paths(base, options), - :force_polling => options['force_polling'], - &(listen_handler(base, options)) - ) - - begin - listener.start - Jekyll.logger.info "Auto-regeneration:", "enabled for '#{options["source"]}'" - - unless options['serving'] - trap("INT") do - listener.stop - puts " Halting auto-regeneration." - exit 0 - end - - loop { sleep 1000 } - end - rescue ThreadError - # You pressed Ctrl-C, oh my! - end - - Jekyll::Commands::Serve.process(options) -end diff --git a/docs/_config.yml b/docs/_config.yml old mode 100755 new mode 100644 index f4f3b21a4..ce28d72c0 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,240 +1,63 @@ # Welcome to Jekyll! # -# This config file is meant for settings that affect your entire site, values -# which you are expected to set up once and rarely need to edit after that. +# This config file is meant for settings that affect your whole blog, values +# which you are expected to set up once and rarely edit after that. If you find +# yourself editing this file very often, consider using Jekyll's data files +# feature for the data you need to update frequently. +# # For technical reasons, this file is *NOT* reloaded automatically when you use -# `jekyll serve`. If you change this file, please restart the server process. +# 'bundle exec jekyll serve'. If you change this file, please restart the server process. -# Site Settings -locale : "en" -title : "Coral Talk Documentation" -title_separator : "-" -name : "The Coral Project" -description : "Documentation and guides for Coral Talk." -url : https://coralproject.github.io # the base hostname & protocol for your site e.g. "https://mmistakes.github.io" -baseurl : /talk # the subpath of your site, e.g. "/blog" -repository : "coralproject/talk" # GitHub username/repo-name e.g. "mmistakes/minimal-mistakes" -teaser : # path of fallback teaser image, e.g. "/assets/images/500x300.png" -# breadcrumbs : false # true, false (default) -words_per_minute : 200 -comments: - provider : # false (default), "disqus", "discourse", "facebook", "google-plus", "staticman", "custom" - disqus: - shortname : # https://help.disqus.com/customer/portal/articles/466208-what-s-a-shortname- - discourse: - server : # https://meta.discourse.org/t/embedding-discourse-comments-via-javascript/31963 , e.g.: meta.discourse.org - facebook: - # https://developers.facebook.com/docs/plugins/comments - appid : - num_posts : # 5 (default) - colorscheme : # "light" (default), "dark" -staticman: - allowedFields : ['name', 'email', 'url', 'message'] - branch : "master" - commitMessage : "New comment." - filename : comment-{@timestamp} - format : "yml" - moderation : true - path : "docs/_data/comments/{options.slug}" # "/_data/comments/{options.slug}" (default) - requiredFields : ['name', 'email', 'message'] - transforms: - email : "md5" - generatedFields: - date: - type : "date" - options: - format : "iso8601" # "iso8601" (default), "timestamp-seconds", "timestamp-milliseconds" -atom_feed: - path : # blank (default) uses feed.xml +# Site settings +# These are used to personalize your new site. If you look in the HTML files, +# you will see them accessed via {{ site.title }}, {{ site.email }}, and so on. +# You can create any custom variable you would like, and they will be accessible +# in the templates via {{ site.myvariable }}. +title: Talk Documentation +description: > # this means to ignore newlines until "baseurl:" + Documentation and guides for Talk from The Coral Project. +baseurl: "/talk" # the subpath of your site, e.g. /blog +url: "https://coralproject.github.io" # the base hostname & protocol for your site, e.g. http://example.com +google_analytics: UA-73335347-5 +versions: + node: 8+ + yarn: 1.0.1+ + mongodb: 3.2+ + redis: 3.2.5+ + docker: 17.06.2+ + docker_compose: 1.14.0+ -# SEO Related -google_site_verification : -bing_site_verification : -alexa_site_verification : -yandex_site_verification : - -# Social Sharing -twitter: - username : -facebook: - username : - app_id : - publisher : -og_image : # Open Graph/Twitter default site image -# For specifying social profiles -# - https://developers.google.com/structured-data/customize/social-profiles -social: - type : # Person or Organization (defaults to Person) - name : # If the user or organization name differs from the site's name - links: # An array of links to social media profiles - -# Analytics -analytics: - provider : false # false (default), "google", "google-universal", "custom" - google: - tracking_id : - - -# Site Author -author: - name : "Your Name" - avatar : # path of avatar image, e.g. "/assets/images/bio-photo.jpg" - bio : "I am an amazing person." - location : "Somewhere" - email : - uri : - bitbucket : - codepen : - dribbble : - flickr : - facebook : - foursquare : - github : - gitlab : - google_plus : - keybase : - instagram : - lastfm : - linkedin : - pinterest : - soundcloud : - stackoverflow : # "123456/username" (the last part of your profile url, e.g. http://stackoverflow.com/users/123456/username) - steam : - tumblr : - twitter : - vine : - weibo : - xing : - youtube : # "https://youtube.com/c/MichaelRoseDesign" - - -# Reading Files -include: - - .htaccess - - swagger.yml - - _pages -exclude: - - "*.sublime-project" - - "*.sublime-workspace" - - vendor - - .asset-cache - - .bundle - - .jekyll-assets-cache - - .sass-cache - - assets/js/plugins - - assets/js/_main.js - - assets/js/vendor - - Capfile - - CHANGELOG - - config - - Gemfile - - Gruntfile.js - - gulpfile.js - - LICENSE - - log - - node_modules - - package.json - - Rakefile - - README.md - - tmp -keep_files: - - .git - - .svn -encoding: "utf-8" -markdown_ext: "markdown,mkdown,mkdn,mkd,md" - - -# Conversion +# Build settings markdown: kramdown -highlighter: rouge -lsi: false -excerpt_separator: "\n\n" -incremental: false - - -# Markdown Processing kramdown: - input: GFM - hard_wrap: false - auto_ids: true - footnote_nr: 1 - entity_output: as_char - toc_levels: 1..6 - smart_quotes: lsquo,rsquo,ldquo,rdquo - enable_coderay: false + syntax_highlighter_opts: + disable : true +plugins: + - jekyll-seo-tag + +# Exclude from processing. +# The following items will not be processed, by default. Create a custom list +# to override the default setting. +# exclude: +# - Gemfile +# - Gemfile.lock +# - node_modules +# - vendor/bundle/ +# - vendor/cache/ +# - vendor/gems/ +# - vendor/ruby/ # Sass/SCSS sass: sass_dir: _sass style: compressed # http://sass-lang.com/documentation/file.SASS_REFERENCE.html#output_style - -# Outputting -permalink: /:categories/:title/ -paginate: 5 # amount of posts to show -paginate_path: /page:num/ -timezone: # http://en.wikipedia.org/wiki/List_of_tz_database_time_zones - - -# Plugins (previously gems:) -plugins: - - jekyll-paginate - - jekyll-sitemap - - jekyll-gist - - jekyll-feed - - jemoji - -# mimic GitHub Pages with --safe -whitelist: - - jekyll-paginate - - jekyll-sitemap - - jekyll-gist - - jekyll-feed - - jemoji - - -# Archives -# Type -# - GitHub Pages compatible archive pages built with Liquid ~> type: liquid (default) -# - Jekyll Archives plugin archive pages ~> type: jekyll-archives -# Path (examples) -# - Archive page should exist at path when using Liquid method or you can -# expect broken links (especially with breadcrumbs enabled) -# - /tags/my-awesome-tag/index.html ~> path: /tags/ -# - path: /categories/ -# - path: / -# category_archive: -# type: liquid -# path: /categories/ -# tag_archive: -# type: liquid -# path: /tags/ -# https://github.com/jekyll/jekyll-archives -# jekyll-archives: -# enabled: -# - categories -# - tags -# layouts: -# category: archive-taxonomy -# tag: archive-taxonomy -# permalinks: -# category: /categories/:name/ -# tag: /tags/:name/ - - -# HTML Compression -# - http://jch.penibelst.de/ -compress_html: - clippings: all - ignore: - envs: development - # Collections collections: docs: output: true - permalink: /:collection/:path/ + permalink: /:path/ # Defaults defaults: @@ -243,10 +66,4 @@ defaults: path: "" type: docs values: - layout: single - read_time: false - author_profile: false - share: false - comments: false - sidebar: - nav: "docs" + layout: doc \ No newline at end of file diff --git a/docs/_data/badges.yaml b/docs/_data/badges.yaml new file mode 100644 index 000000000..2cd431762 --- /dev/null +++ b/docs/_data/badges.yaml @@ -0,0 +1,13 @@ +items: + - title: GitHub release + img: https://img.shields.io/github/release/coralproject/talk.svg + link: https://github.com/coralproject/talk/releases + - title: ImageLayers Size + img: https://img.shields.io/imagelayers/image-size/coralproject/talk/latest.svg + link: https://hub.docker.com/r/coralproject/talk/ + - title: Docker Pulls + img: https://img.shields.io/docker/pulls/coralproject/talk.svg + link: https://hub.docker.com/r/coralproject/talk/ + - title: CircleCI + img: https://img.shields.io/circleci/project/github/coralproject/talk.svg + link: https://circleci.com/gh/coralproject/talk \ No newline at end of file diff --git a/docs/_data/nav.yaml b/docs/_data/nav.yaml new file mode 100644 index 000000000..51b44f025 --- /dev/null +++ b/docs/_data/nav.yaml @@ -0,0 +1,19 @@ +items: + - title: Installation + children: + - title: Talk Quickstart + url: / + - title: Installation from Docker + url: /installation-from-docker/ + - title: Installation from Source + url: /installation-from-source/ + - title: Configuration + children: + - title: Required Configuration + url: /configuration/ + - title: Advanced Configuration + url: /advanced-configuration/ + - title: Plugins + children: + - title: Plugins Overview + url: /plugins/ \ No newline at end of file diff --git a/docs/_data/navigation.yml b/docs/_data/navigation.yml deleted file mode 100755 index 9fe39d103..000000000 --- a/docs/_data/navigation.yml +++ /dev/null @@ -1,74 +0,0 @@ -# main links -main: - - title: "GitHub" - url: https://github.com/coralproject/talk/ - - title: "CircleCI" - url: https://circleci.com/gh/coralproject/talk/ - - title: "Docker" - url: https://hub.docker.com/r/coralproject/talk/ - - title: "Roadmap" - url: https://www.pivotaltracker.com/n/projects/1863625 - - title: "Blog" - url: https://coralproject.net/ - - -docs: - - title: "FAQ" - url: /docs/faq - - title: "Installation" - url: /docs/install/ - children: - - title: "Source" - url: /docs/install/source/ - - title: "Docker" - url: /docs/install/docker/ - - title: "First Setup" - url: /docs/install/setup/ - - title: "Microservices" - url: /docs/install/microservices/ - - title: "Troubleshooting" - url: /docs/install/troubleshooting/ - - title: "Running" - children: - - title: "Configuration" - url: /docs/running/configuration/ - - title: "Secrets" - url: /docs/running/secrets/ - - title: "Plugins" - url: /docs/running/plugins/ - - title: "Database Migrations" - url: /docs/running/migrations/ - - title: "Persistence" - url: /docs/running/persistence/ - - title: "Architecture" - url: /docs/architecture/ - children: - - title: "Tags" - url: /docs/architecture/tags/ - - title: "Metadata" - url: /docs/architecture/metadata/ - - title: "Command Line Interface" - url: /docs/architecture/cli/ - - title: "Client" - url: /docs/architecture/client - - title: "Plugins" - url: /docs/plugins/ - children: - - title: "Quickstart" - url: /docs/plugins/quickstart/ - - title: "Client API" - url: /docs/plugins/client/ - - title: "Server API" - url: /docs/plugins/server/ - - title: "Experimental" - url: /docs/plugins/experimental/ - - title: "Development" - children: - - title: "Tools" - url: /docs/development/tools/ - - title: "Contributor's Guide" - url: /docs/development/contributing/ - - title: "Code of Conduct" - url: /docs/development/code-of-conduct/ - - title: "REST API" - url: /docs/development/rest/ diff --git a/docs/_data/ui-text.yml b/docs/_data/ui-text.yml deleted file mode 100755 index 24760949f..000000000 --- a/docs/_data/ui-text.yml +++ /dev/null @@ -1,802 +0,0 @@ -# User interface text and labels - -# English (default) -# ----------------- -en: &DEFAULT_EN - page : "Page" - pagination_previous : "Previous" - pagination_next : "Next" - breadcrumb_home_label : "Home" - breadcrumb_separator : "/" - menu_label : "Toggle Menu" - toc_label : "On This Page" - ext_link_label : "Direct Link" - less_than : "less than" - minute_read : "minute read" - share_on_label : "Share on" - meta_label : - tags_label : "Tags:" - categories_label : "Categories:" - date_label : "Updated:" - comments_label : "Leave a Comment" - comments_title : "Comments" - more_label : "Learn More" - related_label : "You May Also Enjoy" - follow_label : "Follow:" - feed_label : "Feed" - powered_by : "Powered by" - website_label : "Website" - email_label : "Email" - recent_posts : "Recent Posts" - undefined_wpm : "Undefined parameter words_per_minute at _config.yml" - comment_form_info : "Your email address will not be published. Required fields are marked" - comment_form_comment_label : "Comment" - comment_form_md_info : "Markdown is supported." - comment_form_name_label : "Name" - comment_form_email_label : "Email address" - comment_form_website_label : "Website (optional)" - comment_btn_submit : "Submit Comment" - comment_btn_submitted : "Submitted" - comment_success_msg : "Thanks for your comment! It will show on the site once it has been approved." - comment_error_msg : "Sorry, there was an error with your submission. Please make sure all required fields have been completed and try again." - loading_label : "Loading..." -en-US: - <<: *DEFAULT_EN -en-CA: - <<: *DEFAULT_EN -en-GB: - <<: *DEFAULT_EN -en-AU: - <<: *DEFAULT_EN - -# Spanish -# -------------- -es: &DEFAULT_ES - page : "Página" - pagination_previous : "Anterior" - pagination_next : "Siguiente" - breadcrumb_home_label : "Inicio" - breadcrumb_separator : "/" - menu_label : - toc_label : "Contenidos" - ext_link_label : "Enlace" - less_than : "menos de" - minute_read : "minuto de lectura" - share_on_label : "Compartir" - meta_label : - tags_label : "Etiquetas:" - categories_label : "Categorías:" - date_label : "Actualizado:" - comments_label : "Comentar" - comments_title : - more_label : "Ver más" - related_label : "Podrías ver también" - follow_label : "Seguir:" - feed_label : "Feed" - powered_by : "Powered by" - website_label : "Sitio web" - email_label : "Email" - recent_posts : "Entradas recientes" - undefined_wpm : "Parametro words_per_minute (Palabras por minuto) no definido en _config.yml" - comment_form_info : "Su dirección de correo no será publicada. Se han resaltado los campos requeridos" - comment_form_comment_label : "Comentario" - comment_form_md_info : "Markdown está soportado." - comment_form_name_label : "Nombre" - comment_form_email_label : "Dirección de E-mail" - comment_form_website_label : "Sitio web (opcional)" - comment_btn_submit : "Enviar Commentario" - comment_btn_submitted : "Enviado" - comment_success_msg : "Gracias por su comentario!, Este se visualizará en el sitio una vez haya sido aprobado" - comment_error_msg : "Lo sentimos, ha ocurrido un error al enviar su comentario. Por favor asegurese que todos los campos han sido diligenciados e intente de nuevo" - loading_label : "Cargando..." -es-ES: - <<: *DEFAULT_ES -es-CO: - <<: *DEFAULT_ES - -# French -# ----------------- -fr: &DEFAULT_FR - page : "Page" - pagination_previous : "Précédent" - pagination_next : "Suivant" - breadcrumb_home_label : "Accueil" - breadcrumb_separator : "/" - menu_label : - toc_label : "Sur cette page" - ext_link_label : "Lien direct" - less_than : "moins de" - minute_read : "minute de lecture" - share_on_label : "Partager sur" - meta_label : - tags_label : "Tags :" - categories_label : "Catégories :" - date_label : "Mis à jour :" - comments_label : "Laisser un commentaire" - comments_title : - more_label : "Lire plus" - related_label : "Vous pourriez aimer aussi" - follow_label : "Contact" - feed_label : "Flux" - powered_by : "Propulsé par" - website_label : "Site" - email_label : "Email" - recent_posts : "Posts récents" - undefined_wpm : "Le paramètre words_per_minute n'est pas défini dans _config.yml" - comments_title : "Commentaires" - comment_form_info : "Votre adresse email ne sera pas visible. Les champs obligatoires sont marqués" - comment_form_comment_label : "Commentaire" - comment_form_md_info : "Markdown est supporté." - comment_form_name_label : "Nom" - comment_form_email_label : "Adresse mail" - comment_form_website_label : "Site web (optionnel)" - comment_btn_submit : "Envoyer" - comment_btn_submitted : "Envoyé" - comment_success_msg : "Merci pour votre commentaire, il sera visible sur le site une fois approuvé." - comment_error_msg : "Désolé, une erreur est survenue lors de la soumission. Vérifiez que les champs obligatoires ont été remplis et réessayez." - loading_label : "Chargement..." -fr-FR: - <<: *DEFAULT_FR -fr-BE: - <<: *DEFAULT_FR -fr-CH: - <<: *DEFAULT_FR - -# Turkish -# ----------------- -tr: &DEFAULT_TR - page : "Sayfa" - pagination_previous : "Önceki" - pagination_next : "Sonraki" - breadcrumb_home_label : "Ana Sayfa" - breadcrumb_separator : "/" - menu_label : - toc_label : "İçindekiler" - ext_link_label : "Doğrudan Bağlantı" - less_than : "Şu süreden az: " - minute_read : "dakika tahmini okuma süresi" - share_on_label : "Paylaş" - meta_label : - tags_label : "Etiketler:" - categories_label : "Kategoriler:" - date_label : "Güncelleme tarihi:" - comments_label : "Yorum yapın" - comments_title : "Yorumlar" - more_label : "Daha fazlasını öğrenin" - related_label : "Bunlar ilginizi çekebilir:" - follow_label : "Takip et:" - feed_label : "RSS" - powered_by : "Emeği geçenler: " - website_label : "Web sayfası" - email_label : "E-posta" - recent_posts : "Son yazılar" - undefined_wpm : "_config.yml dosyasında tanımlanmamış words_per_minute parametresi" - comment_form_info : "Email adresiniz gösterilmeyecektir. Zorunlu alanlar işaretlenmiştir" - comment_form_comment_label : "Yorumunuz" - comment_form_md_info : "Markdown desteklenmektedir." - comment_form_name_label : "Adınız" - comment_form_email_label : "Email adresiniz" - comment_form_website_label : "Websiteniz (opsiyonel)" - comment_btn_submit : "Yorum Yap" - comment_btn_submitted : "Gönderildi" - comment_success_msg : "Yorumunuz için teşekkürler! Yorumunuz onaylandıktan sonra sitede gösterilecektir." - comment_error_msg : "Maalesef bir hata oluştu. Lütfen zorunlu olan tüm alanları doldurduğunuzdan emin olun ve sonrasında tekrar deneyin." - loading_label : "Yükleniyor..." -tr-TR: - <<: *DEFAULT_TR - -# Portuguese -# ----------------- -pt: &DEFAULT_PT - page : "Página" - pagination_previous : "Anterior" - pagination_next : "Seguinte" - breadcrumb_home_label : "Início" - breadcrumb_separator : "/" - menu_label : - toc_label : "Nesta Página" - ext_link_label : "Link Direto" - less_than : "menos de" - minute_read : "minutos de leitura" - share_on_label : "Partilhar no" - meta_label : - tags_label : "Etiquetas:" - categories_label : "Categorias:" - date_label : "Atualizado:" - comments_label : "Deixe um Comentário" - comments_title : "Comentários" - more_label : "Saber mais" - related_label : "Também pode gostar de" - follow_label : "Siga:" - feed_label : "Feed" - powered_by : "Feito com" - website_label : "Site" - email_label : "Email" - recent_posts : "Artigos Recentes" - undefined_wpm : "Parâmetro words_per_minute não definido em _config.yml" - comment_form_info : "O seu endereço email não será publicado. Os campos obrigatórios estão assinalados" - comment_form_comment_label : "Comentário" - comment_form_md_info : "Markdown é suportado." - comment_form_name_label : "Nome" - comment_form_email_label : "Endereço Email" - comment_form_website_label : "Site (opcional)" - comment_btn_submit : "Sumbeter Comentário" - comment_btn_submitted : "Submetido" - comment_success_msg : "Obrigado pelo seu comentário! Será visível no site logo que aprovado." - comment_error_msg : "Lamento, ocorreu um erro na sua submissão. Por favor verifique se todos os campos obrigatórios estão corretamente preenchidos e tente novamente." - loading_label : "A carregar..." -# Brazilian Portuguese -pt-BR: - page : "Página" - pagination_previous : "Anterior" - pagination_next : "Próxima" - breadcrumb_home_label : "Home" - breadcrumb_separator : "/" - menu_label : - toc_label : "Nesta página" - ext_link_label : "Link direto" - less_than : "meno que" - minute_read : "minutos de leitura" - share_on_label : "Compartilhe em" - meta_label : - tags_label : "Tags:" - categories_label : "Categorias:" - date_label : "Atualizado em:" - comments_label : "Deixe um comentário" - comments_title : - more_label : "Aprenda Mais" - related_label : "Você Talvez Goste Também" - follow_label : "Acompanhe em" - feed_label : "Feed" - powered_by : "Feito com" - website_label : "Site" - email_label : "Email" - recent_posts : "Postagens recentes" - undefined_wpm : "Parâmetro indefinido em word_per_minute no _config.yml" - comment_form_info : - comment_form_comment_label : - comment_form_md_info : - comment_form_name_label : - comment_form_email_label : - comment_form_website_label : - comment_btn_submit : - comment_btn_submitted : - comment_success_msg : - comment_error_msg : - loading_label : -pt-PT: - <<: *DEFAULT_PT - -# Italian -# ----------------- -it: &DEFAULT_IT - page : "Pagina" - pagination_previous : "Precedente" - pagination_next : "Prossima" - breadcrumb_home_label : "Home" - breadcrumb_separator : "/" - menu_label : - toc_label : "Indice della pagina" - ext_link_label : "Link" - less_than : "meno di" - minute_read : "minuto/i di lettura" - share_on_label : "Condividi" - meta_label : - tags_label : "Tags:" - categories_label : "Categorie:" - date_label : "Aggiornato:" - comments_label : "Scrivi un commento" - comments_title : - more_label : "Scopri di più" - related_label : "Potrebbe Piacerti Anche" - follow_label : "Segui:" - feed_label : "Feed" - powered_by : "Powered by" - website_label : "Website" - email_label : "Email" - recent_posts : "Articoli Recenti" - undefined_wpm : "Parametro words_per_minute non definito in _config.yml" - comment_form_info : "Il tuo indirizzo email non sarà pubblicato. Sono segnati i campi obbligatori" - comment_form_comment_label : "Commenta" - comment_form_md_info : "Il linguaggio Markdown è supportato" - comment_form_name_label : "Nome" - comment_form_email_label : "Indirizzo email" - comment_form_website_label : "Sito Web (opzionale)" - comment_btn_submit : "Invia commento" - comment_btn_submitted : "Inviato" - comment_success_msg : "Grazie per il tuo commento! Verrà visualizzato nel sito una volta che sarà approvato." - comment_error_msg : "C'è stato un errore con il tuo invio. Assicurati che tutti i campi richiesti siano stati completati e riprova." - loading_label : "Caricamento..." -it-IT: - <<: *DEFAULT_IT - -# Chinese (zh-CN Chinese - China) -# ----------------- -zh: &DEFAULT_ZH - page : "页面" - pagination_previous : "向前" - pagination_next : "向后" - breadcrumb_home_label : "首页" - breadcrumb_separator : "/" - menu_label : "切换菜单" - toc_label : "在本页上" - ext_link_label : "直接链接" - less_than : "少于" - minute_read : "分钟 阅读" - share_on_label : "分享" - meta_label : - tags_label : "标签:" - categories_label : "分类:" - date_label : "最新的:" - comments_label : "留下评论" - comments_title : "评论" - more_label : "了解更多" - related_label : "猜您还喜欢" - follow_label : "关注:" - feed_label : "Feed" - powered_by : "技术来自于" - website_label : "网站" - email_label : "电子邮箱" - recent_posts : "最新文章" - undefined_wpm : "_config.yml配置中words_per_minute字段未定义" - comment_form_info : "您的电子邮箱地址并不会被展示。请填写标记为必须的字段。" - comment_form_comment_label : "评论" - comment_form_md_info : "Markdown语法已支持。" - comment_form_name_label : "姓名" - comment_form_email_label : "电子邮箱" - comment_form_website_label : "网站(可选)" - comment_btn_submit : "提交评论" - comment_btn_submitted : "已提交" - comment_success_msg : "感谢您的评论!被批准后它会立即在此站点展示。" - comment_error_msg : "很抱歉,您的提交存在错误。请确保所有必填字段都已填写正确,然后再试一次。" - loading_label : "正在加载..." -zh-CN: - <<: *DEFAULT_ZH -zh-HK: - <<: *DEFAULT_ZH -zh-SG: - <<: *DEFAULT_ZH -# Taiwan (Traditional Chinese) -zh-TW: - page : "頁面" - pagination_previous : "較舊" - pagination_next : "較新" - breadcrumb_home_label : "首頁" - breadcrumb_separator : "/" - menu_label : "切換選單" - toc_label : "本頁" - ext_link_label : "外部連結" - less_than : "少於" - minute_read : "分鐘閱讀" - share_on_label : "分享到" - meta_label : - tags_label : "標籤:" - categories_label : "分類:" - date_label : "更新時間:" - comments_label : "留言" - comments_title : "留言內容" - more_label : "了解更多" - related_label : "猜您有與趣" - follow_label : "追蹤:" - feed_label : "RSS Feed" - powered_by : "Powered by" - website_label : "網站" - email_label : "電子信箱" - recent_posts : "最新文章" - undefined_wpm : "_config.yml 中未定義 words_per_minute" - comment_form_info : "您的電子信箱不會被公開. 必填部份已標記" - comment_form_comment_label : "留言內容" - comment_form_md_info : "支援Markdown語法。" - comment_form_name_label : "名字" - comment_form_email_label : "電子信箱帳號" - comment_form_website_label : "網頁 (可選填)" - comment_btn_submit : "送出留言" - comment_btn_submitted : "已送出" - comment_success_msg : "感謝您的留言! 審核後將會顯示在站上。" - comment_error_msg : "抱歉,部份資料輸入有問題。請確認資料填寫正確後再試一次。" - loading_label : "載入中..." - -# German / Deutsch -# ----------------- -de: &DEFAULT_DE - page : "Seite" - pagination_previous : "Vorherige" - pagination_next : "Nächste" - breadcrumb_home_label : "Home" - breadcrumb_separator : "/" - menu_label : - toc_label : "Auf dieser Seite" - ext_link_label : "Direkter Link" - less_than : "weniger als" - minute_read : "Minuten zum lesen" - share_on_label : "Teilen auf" - meta_label : - tags_label : "Tags:" - categories_label : "Kategorien:" - date_label : "Aktualisiert:" - comments_label : "Hinterlassen sie einen Kommentar" - comments_title : "Kommentare" - more_label : "Mehr anzeigen" - related_label : "Ihnen gefällt vielleicht auch" - follow_label : "Folgen:" - feed_label : "Feed" - powered_by : "Powered by" - website_label : "Webseite" - email_label : "E-Mail" - recent_posts : "Aktuelle Beiträge" - undefined_wpm : "Undefinierter Parameter words_per_minute in _config.yml" - comment_form_info : "Ihre E-Mail Adresse wird nicht veröffentlicht. Benötigte Felder sind markiert" - comment_form_comment_label : "Kommentar" - comment_form_md_info : "Markdown wird unterstützt." - comment_form_name_label : "Name" - comment_form_email_label : "E-Mail Addresse" - comment_form_website_label : "Webseite (optional)" - comment_btn_submit : "Kommentar absenden" - comment_btn_submitted : "Versendet" - comment_success_msg : "Danke für ihren Kommentar! Er wird auf der Seite angezeigt, nachdem er geprüft wurde." - comment_error_msg : "Entschuldigung, es gab einen Fehler. Bitte füllen sie alle benötigten Felder aus und versuchen sie es erneut." - loading_label : "Lade..." -de-DE: - <<: *DEFAULT_DE -de-AT: - <<: *DEFAULT_DE -de-CH: - <<: *DEFAULT_DE -de-BE: - <<: *DEFAULT_DE -de-LI: - <<: *DEFAULT_DE -de-LU: - <<: *DEFAULT_DE - -# Nepali (Nepal) -# ----------------- -ne: &DEFAULT_NE - page : "पृष्‍ठ" - pagination_previous : "अघिल्लो" - pagination_next : "अर्को" - breadcrumb_home_label : "गृह" - breadcrumb_separator : "/" - menu_label : "टगल मेनु" - toc_label : "यो पृष्‍ठमा" - ext_link_label : "सिधा सम्पर्क" - less_than : "कम्तिमा" - minute_read : "मिनेट पढ्नुहोस्" - share_on_label : "शेयर गर्नुहोस्" - meta_label : - tags_label : "ट्यागहरू:" - categories_label : "वर्गहरु:" - date_label : "अद्यावधिक:" - comments_label : "टिप्पणी दिनुहोस्" - comments_title : "टिप्पणीहरू" - more_label : "अझै सिक्नुहोस्" - related_label : "तपाईं रुचाउन सक्नुहुन्छ " - follow_label : "पछ्याउनुहोस्:" - feed_label : "फिड" - powered_by : "Powered by" - website_label : "वेबसाइट" - email_label : "इमेल" - recent_posts : "ताजा लेखहरु" - undefined_wpm : "अपरिभाषित प्यारामिटर शब्दहरू_प्रति_मिनेट at _config.yml" - comment_form_info : "तपाइँको इमेल ठेगाना प्रकाशित गरिने छैन।आवश्यक जानकारीहरुमा चिन्ह लगाइको छ" - comment_form_comment_label : "टिप्पणी" - comment_form_md_info : "मार्कडाउन समर्थित छ।" - comment_form_name_label : "नाम" - comment_form_email_label : "इमेल ठेगाना" - comment_form_website_label : "वेबसाइट (वैकल्पिक)" - comment_btn_submit : "टिप्पणी दिनुहोस् " - comment_btn_submitted : "टिप्पणी भयो" - comment_success_msg : "तपाईंको टिप्पणीको लागि धन्यवाद! एक पटक यो अनुमोदन गरेपछी यो साइटमा देखाउनेछ।" - comment_error_msg : "माफ गर्नुहोस्, तपाईंको टिप्पणी त्रुटि थियो।सबै आवश्यक जानकारीहरु पूरा गरिएको छ भने निश्चित गर्नुहोस् र फेरि प्रयास गर्नुहोस्।" - loading_label : "लोड हुँदैछ ..." -ne-NP: - <<: *DEFAULT_NE - -# Korean -# -------------- -ko: &DEFAULT_KO - page : "페이지" - pagination_previous : "이전" - pagination_next : "다음" - breadcrumb_home_label : "Home" - breadcrumb_separator : "/" - menu_label : "토글 메뉴" - toc_label : "On This Page" - ext_link_label : "직접 링크" - less_than : "최대" - minute_read : "분 소요" - share_on_label : "공유하기" - meta_label : - tags_label : "태그:" - categories_label : "카테고리:" - date_label : "업데이트:" - comments_label : "댓글남기기" - comments_title : "댓글" - more_label : "더 보기" - related_label : "참고" - follow_label : "팔로우:" - feed_label : "피드" - powered_by : "Powered by" - website_label : "웹사이트" - email_label : "이메일" - recent_posts : "최근 포스트" - undefined_wpm : "Undefined parameter words_per_minute at _config.yml" - comment_form_info : "이메일은 공개되지 않습니다. 작성 필요 필드:" - comment_form_comment_label : "댓글" - comment_form_md_info : "마크다운을 지원합니다." - comment_form_name_label : "이름" - comment_form_email_label : "이메일" - comment_form_website_label : "웹사이트(선택사항)" - comment_btn_submit : "댓글 등록" - comment_btn_submitted : "등록됨" - comment_success_msg : "감사합니다! 댓글이 머지된 후 확인하실 수 있습니다." - comment_error_msg : "댓글 등록에 문제가 있습니다. 필요 필드를 작성했는지 확인하고 다시 시도하세요." - loading_label : "로딩중..." -ko-KR: - <<: *DEFAULT_KO - -# Russian / Русский -# ----------------- -ru: &DEFAULT_RU - page : "Страница" - pagination_previous : "Предыдущая" - pagination_next : "Следующая" - breadcrumb_home_label : "Главная" - breadcrumb_separator : "/" - menu_label : "Выпадающее меню" - toc_label : "Содержание" - ext_link_label : "Прямая ссылка" - less_than : "менее" - minute_read : "мин на чтение" - share_on_label : "Поделиться" - meta_label : - tags_label : "Метки:" - categories_label : "Разделы:" - date_label : "Дата изменения:" - comments_label : "Оставить комментарий" - comments_title : "Комментарии" - more_label : "Читать далее" - related_label : "Вам также может понравиться" - follow_label : "Связаться со мной:" - feed_label : "RSS-лента" - powered_by : "Сайт работает на" - website_label : "Сайт" - email_label : "Электронная почта" - recent_posts : "Свежие записи" - undefined_wpm : "Не определён параметр words_per_minute в _config.yml" - comment_form_info : "Ваш адрес электронной почты не будет опубликован. Обязательные поля помечены" - comment_form_comment_label : "Комментарий" - comment_form_md_info : "Поддерживается синтаксис Markdown." - comment_form_name_label : "Имя" - comment_form_email_label : "Электронная почта" - comment_form_website_label : "Ссылка на сайт (необязательно)" - comment_btn_submit : "Оставить комментарий" - comment_btn_submitted : "Отправлено" - comment_success_msg : "Спасибо за Ваш комментарий! Он будет опубликован на сайте после проверки." - comment_error_msg : "К сожалению, произошла ошибка с отправкой комментария. Пожалуйста, убедитесь, что все обязательные поля заполнены и попытайтесь снова." - loading_label : "Отправка..." -ru-RU: - <<: *DEFAULT_RU - -# Lithuanian / Lietuviškai -# ----------------- -lt: &DEFAULT_LT - page : "Puslapis" - pagination_previous : "Ankstesnis" - pagination_next : "Sekantis" - breadcrumb_home_label : "Pagrindinis" - breadcrumb_separator : "/" - menu_label : "Meniu rodymas" - toc_label : "Turinys" - ext_link_label : "Tiesioginė nuoroda" - less_than : "mažiau nei" - minute_read : "min. skaitymo" - share_on_label : "Pasidalinti" - meta_label : - tags_label : "Žymės:" - categories_label : "Kategorijos:" - date_label : "Atnaujinta:" - comments_label : "Palikti komentarą" - comments_title : "Komentaras" - more_label : "Skaityti daugiau" - related_label : "Taip pat turėtų patikti" - follow_label : "Sekti:" - feed_label : "Šaltinis" - powered_by : "Sukurta su" - website_label : "Tinklapis" - email_label : "El. paštas" - recent_posts : "Naujausi įrašai" - undefined_wpm : "Nedeklaruotas parametras words_per_minute faile _config.yml" - comment_form_info : "El. pašto adresas nebus viešinamas. Būtini laukai pažymėti." - comment_form_comment_label : "Komentaras" - comment_form_md_info : "Markdown palaikomas." - comment_form_name_label : "Vardas" - comment_form_email_label : "El. paštas" - comment_form_website_label : "Tinklapis (nebūtina)" - comment_btn_submit : "Komentuoti" - comment_btn_submitted : "Įrašytas" - comment_success_msg : "Ačiū už komentarą! Jis bus parodytas kai bus patvirtintas." - comment_error_msg : "Atleiskite, įvyko netikėta klaida įrašant komentarą. Pasitikrinkite ar užpildėte visus būtinus laukus ir pamėginkite dar kartą." - loading_label : "Kraunama..." -lt-LT: - <<: *DEFAULT_LT - -# Greek -# -------------- -gr: &DEFAULT_GR - page : "Σελίδα" - pagination_previous : "Προηγούμενo" - pagination_next : "Επόμενo" - breadcrumb_home_label : "Αρχική" - breadcrumb_separator : "/" - menu_label : "Μενού" - toc_label : "Περιεχόμενα" - ext_link_label : "Εξωτερικός Σύνδεσμος" - less_than : "Λιγότερο από" - minute_read : "λεπτά ανάγνωσης" - share_on_label : "Μοιραστείτε το" - meta_label : - tags_label : "Ετικέτες:" - categories_label : "Κατηγορίες:" - date_label : "Ενημερώθηκε:" - comments_label : "Αφήστε ένα σχόλιο" - comments_title : "Σχόλια" - more_label : "Διάβαστε περισσότερα" - related_label : "Σχετικές αναρτήσεις" - follow_label : "Ακολουθήστε:" - feed_label : "RSS Feed" - powered_by : "Δημιουργήθηκε με" - website_label : "Ιστοσελίδα" - email_label : "Email" - recent_posts : "Τελευταίες αναρτήσεις" - undefined_wpm : "Δεν έχει οριστεί η παράμετρος words_per_minute στο αρχείο _config.yml" - comment_form_info : "Η διεύθυνση email σας δεν θα δημοσιευθεί. Τα απαιτούμενα πεδία εμφανίζονται με αστερίσκο" - comment_form_comment_label : "Σχόλιο" - comment_form_md_info : "Το πεδίο υποστηρίζει Markdown." - comment_form_name_label : "Όνομα" - comment_form_email_label : "Διεύθυνση email" - comment_form_website_label : "Ιστοσελίδα (προαιρετικό)" - comment_btn_submit : "Υπόβαλε ένα σχόλιο" - comment_btn_submitted : "Έχει υποβληθεί" - comment_success_msg : "Ευχαριστούμε για το σχόλιό σας! Θα εμφανιστεί στην ιστοσελίδα αφού εγκριθεί." - comment_error_msg : "Λυπούμαστε, παρουσιάστηκε σφάλμα με την υποβολή σας. Παρακαλούμε βεβαιωθείτε ότι έχετε όλα τα απαιτούμενα πεδία συμπληρωμένα και δοκιμάστε ξανά." - loading_label : "Φόρτωση..." -gr-GR: - <<: *DEFAULT_GR - -# Swedish -# ----------------- -sv: &DEFAULT_SV - page : "Sidan" - pagination_previous : "Föregående" - pagination_next : "Nästa" - breadcrumb_home_label : "Hem" - breadcrumb_separator : "/" - menu_label : "Meny ridå" - toc_label : "På denna sida" - ext_link_label : "Direkt länk" - less_than : "mindre än" - minute_read : "minut läsning" - share_on_label : "Dela på" - meta_label : - tags_label : "Taggar:" - categories_label : "Kategorier:" - date_label : "Uppdaterades:" - comments_label : "Lämna en kommentar" - comments_title : "Kommentarer" - more_label : "Lär dig mer" - related_label : "Du kanske vill även läsa:" - follow_label : "Följ:" - feed_label : "Flöde" - powered_by : "Framställd med" - website_label : "Webbsida" - email_label : "E-post" - recent_posts : "Senaste inlägg" - undefined_wpm : "Odefinerade parametrar words_per_minute i _config.yml" - comment_form_info : "Din e-post adress kommer inte att publiceras. Obligatoriska fält är markerade." - comment_form_comment_label : "Kommentar" - comment_form_md_info : "Använd Markdown för text-formateringen." - comment_form_name_label : "Namn" - comment_form_email_label : "E-post adress" - comment_form_website_label : "Webdsida (valfritt)" - comment_btn_submit : "Skicka en kommentar" - comment_btn_submitted : "Kommentaren har tagits emot" - comment_success_msg : "Tack för din kommentar! Den kommer att visas på sidan så fort den har godkännts." - comment_error_msg : "Tyvärr det har blivit något fel i en av fälten, se till att du fyller i alla rutor och försök igen." - loading_label : "Laddar..." -sv-SE: - <<: *DEFAULT_SV -sv-FI: - <<: *DEFAULT_SV - -# Dutch -# ----------------- -nl: &DEFAULT_NL - page : "Pagina" - pagination_previous : "Vorige" - pagination_next : "Volgende" - breadcrumb_home_label : "Home" - breadcrumb_separator : "/" - menu_label : "Wissel Menu" - toc_label : "Op deze pagina" - ext_link_label : "Directe Link" - less_than : "minder dan" - minute_read : "minuut gelezen" - share_on_label : "Deel op" - meta_label : - tags_label : "Labels:" - categories_label : "Categorieën:" - date_label : "Bijgewerkt:" - comments_label : "Laat een reactie achter" - comments_title : "Commentaren" - more_label : "Meer informatie" - related_label : "Bekijk ook eens" - follow_label : "Volg:" - feed_label : "Feed" - powered_by : "Aangedreven door" - website_label : "Website" - email_label : "Email" - recent_posts : "Recente berichten" - undefined_wpm : "Niet gedefinieerde parameter words_per_minute bij _config.yml" - comment_form_info : "Uw e-mailadres wordt niet gepubliceerd. Verplichte velden zijn gemarkeerd" - comment_form_comment_label : "Commentaar" - comment_form_md_info : "Markdown wordt ondersteund." - comment_form_name_label : "Naam" - comment_form_email_label : "E-mailadres" - comment_form_website_label : "Website (optioneel)" - comment_btn_submit : "Commentaar toevoegen" - comment_btn_submitted : "Toegevoegd" - comment_success_msg : "Bedankt voor uw reactie! Het zal op de site worden weergegeven zodra het is goedgekeurd." - comment_error_msg : "Sorry, er is een fout opgetreden bij uw inzending. Zorg ervoor dat alle vereiste velden zijn voltooid en probeer het opnieuw." - loading_label : "Laden..." -nl-BE: - <<: *DEFAULT_NL -nl-NL: - <<: *DEFAULT_NL - -# Indonesian -# ----------------- -id: &DEFAULT_ID - page : "Halaman" - pagination_previous : "Kembali" - pagination_next : "Maju" - breadcrumb_home_label : "Home" - breadcrumb_separator : "/" - menu_label : "Menu Toggle" - toc_label : "Pada Halaman Ini" - ext_link_label : "Link langsung" - less_than : "Kurang dari" - minute_read : "Waktu baca" - share_on_label : "Berbagi di" - meta_label : - tags_label : "Golongan:" - categories_label : "Kategori:" - date_label : "Diupdate:" - comments_label : "Tinggalkan komentar" - comments_title : "Komentar" - more_label : "Pelajari lagi" - related_label : "Anda juga akan suka" - follow_label : "Ikuti:" - feed_label : "Feed" - powered_by : "Didukung oleh" - website_label : "Website" - email_label : "Email" - recent_posts : "Posting terbaru" - undefined_wpm : "Parameter terdeskripsi words_per_minute di _config.yml" - comment_form_info : "Email Anda tidak akan dipublish. Kolom yang diperlukan ditandai" - comment_form_comment_label : "Komentar" - comment_form_md_info : "Markdown disupport." - comment_form_name_label : "Nama" - comment_form_email_label : "Alamat email" - comment_form_website_label : "Website (opsional)" - comment_btn_submit : "Submit Komentar" - comment_btn_submitted : "Telah disubmit" - comment_success_msg : "Terimakasih atas komentar Anda! Komentar ini akan tampil setelah disetujui." - comment_error_msg : "Maaf, ada kesalahan pada submisi Anda. Pastikan seluruh kolom sudah dilengkapi dan coba kembali." - loading_label : "Sedang meload..." -id-ID: - <<: *DEFAULT_ID - -# Another locale -# -------------- -# diff --git a/docs/_docs/00-01-faq.md b/docs/_docs/00-01-faq.md deleted file mode 100644 index 77b7b86ed..000000000 --- a/docs/_docs/00-01-faq.md +++ /dev/null @@ -1,117 +0,0 @@ ---- -title: Frequently Asked Questions -permalink: /docs/faq/ ---- - -{% include toc %} - -### My site doesn't use HSTS headers, how do I stop Talk from sending them too? - -You can specify the configuration option `TALK_HELMET_CONFIGURATION` and set it -to: - -``` -TALK_HELMET_CONFIGURATION={"hsts": false} -``` - -Which will disable the HSTS module. See the -[helmet](https://github.com/helmetjs/helmet) repository for more information on -how to configure other security middleware used by default. - -### How are new stories/assets added to Talk? Is there an API? - -There are three ways that new assets can make their way into Talk: - -- Just in time -- Active -- Manual - -#### Just in Time asset creation - -Talk ships with a _just in time_ mechanism that works out of the box without -integration with any CMS or manual work needed. - -The _just in time_ flow looks like this: - -* Request comes in for a stream on an asset that doesn't yet exist. -* Talk screens the domain against the domain whitelist, fails if doesn't pass. -* Then, concurrently - * Talk creates a new asset record and returns the stream data (which will be - empty) - * Schedules a job to scrape the new page and fill in asset information. - -The scraping mechanism utilizes -[metascraper](https://www.npmjs.com/package/metascraper) and is queued using the -[Que](https://www.npmjs.com/package/kue). If your Talk deployments is configured -to run separate job worker cluster, scraping will be performed by them. - -#### Active (or push based) asset creation - -If tighter CMS integration is required to push custom data into assets and/or -keep data in sync as changes are made in a CMS an _active_ push based workflow -must be implemented. - -This is an ideal candidate for a plugin. If you are interested in working on it, -please [contact us](https://coralproject.net/contact)! - -#### Manual asset creation - -Sometimes you want to load a lot of assets into the database. The most common -use case for this is populating the database during an initial installation. We -recommend writing a script that transforms the data from it's source and inserts -it into the _assets_ collection. - -For current schema information, please see the -[asset model](https://github.com/coralproject/talk/blob/master/models/asset.js). - -### Where are your http API docs? - -Coral relies on GraphQL for the vast majority of it's client and server -communication. All core queries, mutations and subscriptions are defined along -with types and comments in our central -[TypeDef](https://github.com/coralproject/talk/blob/master/graph/typeDefs.graphql). -For plugin graph api typedefs, see each plugin's `/server/` directory. - -In addition, Talk Server ships with -[GraphiQL](https://github.com/graphql/graphiql). GraphiQL provides a full data -layer IDE including interactive documentation. The autocomplete and -documentation are populated from introspection meaning that Core _and plugin_ -apis can be explored. - -To access GraphiQL: - -* [Install Talk](install-source). -* Open http://localhost:3000/api/v1/graph/iql in your browser. (Note, your server an port may differ.) - -### Where is documentation for a specific component? - -We strive for clear inline documentation across our codebase, but have gaps. -Contributions to documentation would be greatly appreciated and is a great way -to start contributing to the project! - -If you are considering changing a core component (aka, one that is not in a -plugin), you are entering the realm of a core developer. We strongly ask that -you reach out the coral team before forking and changing core code. We are glad -to help talk through your product need and come up with a strategy for -implementing as a plugin, or working with you to extend the plugin API for your -use case. - -### How do I contribute to these docs? - -Contributions to the docs are much appreciated and a great way to get involved -in the project. - -Fork the Talk repo, clone it locally (no need to go through the install from -source process), then: - -``` -cd docs -docker run --rm --volume=$PWD:/srv/jekyll -p 127.0.0.1:4000:4000 -it jekyll/jekyll:pages bash -c "bundle install && jekyll serve" -``` - -You can edit the files in docs with any editor and view the live updates in a -browser by hitting From the docs directory. Then visit: -[http://127.0.0.1:4000/talk/](http://127.0.0.1:4000/talk/). - -Once you've made the changes, file a PR back to the `coralproject/talk` -repository. diff --git a/docs/_docs/01-01-install.md b/docs/_docs/01-01-install.md deleted file mode 100644 index 055217797..000000000 --- a/docs/_docs/01-01-install.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: Installation Overview -permalink: /docs/install/ ---- - -## Requirements - -Talk requires MongoDB and Redis. - -- MongoDB ^3.2 - [Docs](https://docs.mongodb.com/manual/installation/) -- Redis ^3.2.5 - [Docs](https://redis.io/topics/quickstart) - -## Installation method - -While Talk can be installed in many ways, we support two install paths: - -* [Install from Source](source) (development) -* [Install via Docker](docker) (deployment) - -If you have success installing Talk in another way, please consider -[contributing to this documentation]({{ "/docs/faq/" | absolute_url }}#how-do-i-contribute-to-these-docs)! diff --git a/docs/_docs/01-02-install-docker.md b/docs/_docs/01-02-install-docker.md deleted file mode 100644 index 7fd6f6ddf..000000000 --- a/docs/_docs/01-02-install-docker.md +++ /dev/null @@ -1,150 +0,0 @@ ---- -title: Installation From Docker -permalink: /docs/install/docker/ ---- - -We currently support packaging the Talk application via Docker, which automates -the dependency install and asset build process. This is the recommended way to -deploy the application when used in production. - -Available as [coralproject/talk](https://hub.docker.com/r/coralproject/talk/) on Docker Hub. - -Images are tagged using the following notation: - -- `x` (where `x` is the major version number): any minor or patch updates will - be included in this. If you're ok getting new features occasionally and all - the bug fixes, this is the tag for you. -- `x.y` (where `y` is the minor version number): any patch updates will be - included with this tag. If you like getting fixes and having features change - only when you want, this is the tag for you. **(recommended)** -- `x.y.z` (where `z` is the patch version): this tag never gets updated, and - essentially freezes your version, this should only be used when you are either - extending Talk or are sure of a specific version you want to freeze. - -We provide tags with `*-onbuild` that can be used for easy plugin integration and -acts as a customization endpoint. Instructions are provided in the `PLUGINS.md` -document as to how to use it. - -### Requirements - -There are some runtime requirements for running Talk for Docker: - -- [Docker](https://www.docker.com/) v1.13.0 or later -- [Docker Compose](https://docs.docker.com/compose/) v1.10.0 or later - -_Please be sure to check the versions of these requirements. Incorrect versions -of these may lead to unexpected errors!_ - -### Installing - -An example docker-compose.yml: - -```yaml -version: '2' -services: - talk: - image: coralproject/talk:latest - restart: always - ports: - - "5000:5000" - depends_on: - - mongo - - redis - environment: - - TALK_MONGO_URL=mongodb://mongo/talk - - TALK_REDIS_URL=redis://redis - - TALK_ROOT_URL=http://localhost:5000 - - TALK_JWT_SECRET=password - - TALK_FACEBOOK_APP_ID=12345 - - TALK_FACEBOOK_APP_SECRET=123abc - mongo: - image: mongo:3.2 - restart: always - volumes: - - mongo:/data/db - redis: - image: redis:3.2 - restart: always - volumes: - - redis:/data -volumes: - mongo: - external: false - redis: - external: false -``` - -At this stage, you should refer to the [configuration](https://coralproject.github.io/talk/docs/running/configuration/) -for configuration variables that are specific to your installation. Some -pre-defined fields have been filled in the above example which are consistent -with Docker Compose naming conventions for [Docker Links](https://docs.docker.com/compose/networking/#links). - -### Scaling - -If you are interested in splitting apart services, you can simply adjust the -command being executed in the container to optimize for your use case. An -example would be if you wanted to run the API server and the job processor -on different machines. You can achieve this easily with docker compose: - -```yaml -version: '2' -services: - talk-api: - image: coralproject/talk:latest - command: cli serve - restart: always - ports: - - "5000:5000" - depends_on: - - mongo - - redis - environment: - - TALK_MONGO_URL=mongodb://mongo/talk - - TALK_REDIS_URL=redis://redis - talk-jobs: - image: coralproject/talk:latest - command: cli jobs process - restart: always - ports: - - "5001:5000" - depends_on: - - mongo - - redis - environment: - - TALK_MONGO_URL=mongodb://mongo/talk - - TALK_REDIS_URL=redis://redis - mongo: - image: mongo:3.2 - restart: always - volumes: - - mongo:/data/db - redis: - image: redis:3.2 - restart: always - volumes: - - redis:/data -volumes: - mongo: - external: false - redis: - external: false -``` - -Note that the only difference is in the `command` key. From this, you are able -to discretely control which modules are running in order to have the maximum -flexibility when managing your application. - -### Running - -If you're using docker compose: - -```bash -# Start the services using compose -docker-compose up -d -``` - -If you're using plain docker: - -```bash -docker run -d -P coralproject/talk:latest -``` diff --git a/docs/_docs/01-03-install-source.md b/docs/_docs/01-03-install-source.md deleted file mode 100644 index 443d233c4..000000000 --- a/docs/_docs/01-03-install-source.md +++ /dev/null @@ -1,77 +0,0 @@ ---- -title: Installation From Source -permalink: /docs/install/source/ ---- - -This provides information on how to setup the application from source. Note that -this is not recommended for production deploys, but will work for development -and testing purposes. - -## Requirements - -There are some runtime requirements for running Talk from source: - -- [Node](https://nodejs.org/) ~7.8 -- [Yarn](https://yarnpkg.com/) ^0.22.0 - -_Please be sure to check the versions of these requirements. Incorrect versions -of these may lead to unexpected errors!_ - -## Installing - -### Download - -It is highly recommended that you download a released version as the code -available in `master` may not be stable. You can download the latest release -from the [releases page](https://github.com/coralproject/talk/releases). - -You can also clone the git repository via: - -```bash -git clone https://github.com/coralproject/talk.git -``` - -### Building - -We now have to install the dependencies and build the static assets. - -```bash -# Install package dependencies -yarn - -# Build static files -yarn build -``` - -After you create/modify the `plugins.json` (refer to `PLUGINS.md` for plugin -docs) file, you can re-run the following to install their dependencies: - -```bash -# Reconcile plugins -./bin/cli plugins reconcile - -# Build static files -yarn build -``` - -## Running - -Refer to the [configuration](https://coralproject.github.io/talk/docs/running/configuration/) page for required configuration variables to add to the -environment. - -You can start the server after configuring the server using the command: - -```bash -yarn start -``` - -This will setup the server to serve everything on a single node.js process and -is designed to be used in production. - -You can see other scripts we've made available by consulting the `package.json` -file under the `scripts` key including: - -- `yarn test` run unit tests -- `yarn build-watch` watch for changes to client files and build static assets -- `yarn dev-start` watch for changes to server files and reload the server while - also sourcing a `.env` file in your local directory for configuration diff --git a/docs/_docs/01-04-install-setup.md b/docs/_docs/01-04-install-setup.md deleted file mode 100644 index c213ba78f..000000000 --- a/docs/_docs/01-04-install-setup.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: First Setup -permalink: /docs/install/setup/ ---- - -Once you've installed Talk (either via Docker or source), you still need to -setup the application. If you are unfamiliar with any terminology used in the -setup process, refer to the `TERMINOLOGY.md` document. - -## Via Web - -If you want to perform your setup via the web, you can navigate to your -installation of Talk at the path `/admin/install`. There you will be asked a -series of questions for your installation. - -## Via CLI - -If you want to perform your setup through the terminal, you can simply run: - -```bash -cli setup -``` - -And follow the instructions to perform initial setup and create your first user -account. - - -# Usage - -After setup is complete, you can then refer to the `/admin/configure` path to -get the embed code that you can copy/paste onto your blog or website in order to -start using Talk. - -_In order for the embed to work correctly, you will need to whitelist the domain -that is allowed to embed your site on the `/admin/configure` page, failure to do -so will result in the comment stream not loading._ diff --git a/docs/_docs/01-05-install-microservices.md b/docs/_docs/01-05-install-microservices.md deleted file mode 100644 index dc5ff112e..000000000 --- a/docs/_docs/01-05-install-microservices.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: Microservice Deployments -permalink: /docs/install/microservices/ ---- - -In Talk, we seek to deliver the simplicity of a monolith with the advantages of -a microservice based infrastructure for those who want them. - -To accomplish this, Talk has the ability to run with subsets of its overall -functionality and contains architecture that allows them to operate logically as -microservices when running in a single environment. - -## Talk Server Functionalities - -The Talk server serves several logically/architecturally distinct functions: - -* A web server that - * serves "public" assets (aka, the comment embed) - * the GraphQL endpoints -* A web socket server that handles subscriptions. -* A jobs processor that handles queued operations. - -In the documentation so far, we've discussed how to deploy all of these -functionalities bundled into a single monolith application. This is convenient -as there is minimal configuration and horizontal scaling is as easy as upping -the number of servers behind a single load balancer. - -## Separating Talk into Microservices - -Talk can be run in two or more separate clusters of servers by -enabling/disabling different bits of functionality: webserver, socket server and -jobs server. - -Each microservice would deploy with the same codebase and configuration. - -Note that the `cli serve` command, which is responsible for starting the server, -contains flags that control whether `jobs` and `websockets` are enabled. - -``` -talk :) ]$ bin/cli serve --help - - Options: - - ... - -j, --jobs enable job processing on this thread - -w, --websockets enable the websocket (subscriptions) handler on this thread - ... -``` - -Each Talk Microservice cluster can be deployed in an identical manner described -in the other docs in this section with the omission of the `-j` and/or `-w` -flags. - -With routing logic in front of the webserver cluster, separation between public -and protected assets can be achieved. - -## When should I consider separating? - -Consider a microservice deployment if: - -* you are running plugins that require intensive job processing -* you do not want to simplicity of single cluster horizontal scaling and want to - tune the economy and performance of your install. -* You run into scaling issues serving websockets - -At scale, combining separate concerns in a single process makes it very -difficult to understand what is taking up resources. With microservices, each -server could be configured to sit behind it's own load balance and scale -independently. Each variety of process can always have just enough resources. - -An install that heavily utilizes the jobs queue could see delays in http service -because of heavy jobs processes and/or delays in the execution of jobs processes -due to increased server load as a result of Node's single thread infrastructure. - -## Deployment Methodologies - -Note that there is no flag to separate the http routes on the webserver. -Separating the http server functionalities can be accomplished by the routing of -various routes to the correct http server via an external upstream proxy like -Google Cloud's Load Balancer, AWS's ELB, or a websever like NGINX/Apache. This -can ensure that sensitive areas, such as the `/admin/` route are not available -outside the firewall. - -Talk's job processors are synchronized by Redis, so as long as all Talk -instances access the same Redis cluster no additional configuration is needed -when launching an independent jobs cluster. - -If there are any features of Talk that you believe should be disable-able via -server flags, please let us know and consider contributing it to the project! - -## Deployment Flows/Scripts - -We do not currently support any microservice based deployment flows. If you -develop one yourself that is completely based on open source tooling, please -consider contributing it to the project! diff --git a/docs/_docs/01-06-install-troubleshooting.md b/docs/_docs/01-06-install-troubleshooting.md deleted file mode 100644 index 233812b1c..000000000 --- a/docs/_docs/01-06-install-troubleshooting.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Installation Troubleshooting -permalink: /docs/install/troubleshooting/ ---- - -This page tracks common issues that arise when installing Talk and provides resolutions. - -## The Talk server seems to be working but the stream isn't showing up on my page. - -Talk employs a _domain whitelist_ that controls which sites can contain comment threads. This prevents malicious folks from using your server to embed streams on unwanted pages. - -If your comment thread isn't showing: - -1. Log into your admin panel -1. Go to the Configure tab -1. Select the Tech Settings submenu -1. Ensure that your Domain is the Permitted Domains list - -Note: if your site has multiple subdomains, listing the domain itself (ie: `mydomain.com`) will enable Talk on all subdomains. If you would like to restrict Talk to certain subdomains, you must list all of them here (ie: `thisone.mydomain.com thatone.mydomain.com`). diff --git a/docs/_docs/02-01-configuration.md b/docs/_docs/02-01-configuration.md deleted file mode 100644 index 2c7b9bc8a..000000000 --- a/docs/_docs/02-01-configuration.md +++ /dev/null @@ -1,229 +0,0 @@ ---- -title: Configuration -permalink: /docs/running/configuration/ ---- - -{% include toc %} - -## Overview -{:.no_toc} - -Talk, like many web applications, requires manual configuration via environment -variables to configure the server for your specific needs. This is following the -standard [12 Factor App Manifesto](https://12factor.net/) which requires that -said configuration lives as environment variables. - -During development, we can utilize a `.env` file, which takes the form of -`NAME=VALUE`. For example: - -```bash -TALK_MONGO_URL=mongodb://some-awesome-mongo-instance -TALK_REDIS_URL=redis://some-awesome-redis-instance -TALK_ROOT_URL=https://my-awesome-talk.com -# ... and so on -``` - -When you place a file titled `.env` at the root of the project, and start the -application with `yarn dev-start`, it will read in the contents of the `.env` -file as if they were environment variables. This is done via the -[dotenv](https://github.com/motdotla/dotenv) package. In production, using this -method is discouraged, as it promotes bad practices such as storing config in a -file. - -## Variables - -The Talk application looks for the following configuration values either as -environment variables. Refer to the -[config.js](https://github.com/coralproject/talk/blob/master/config.js) file to -see how the configuration is parsed. - -### Webpack - -These are only used during the webpack build. - -- `TALK_THREADING_LEVEL` (_optional_) - specify the maximum depth of the comment - thread. (Default `3`) -- `TALK_DEFAULT_STREAM_TAB` (_optional_) - specify the default stream tab in the - admin. (Default `all`) -- `TALK_DISABLE_EMBED_POLYFILL` (_optional_) - when set to `TRUE`, the build process will not include the [babel-polyfill](https://babeljs.io/docs/usage/polyfill/) in the embed.js target. (Default `FALSE`) - -### Database - -- `TALK_MONGO_URL` (*required*) - the database connection string for the MongoDB database. -- `TALK_REDIS_URL` (*required*) - the database connection string for the Redis database. - -#### Advanced -{:.no_toc} - -- `TALK_REDIS_CLIENT_CONFIG` (_optional_) - configuration overrides for the - redis client configuration in a JSON encoded string. Configuration is - overridden as the second parameter to the redis client constructor, and is - merged with default configuration. (Default `{}`) -- `TALK_REDIS_RECONNECTION_BACKOFF_FACTOR` (_optional_) - the time factor that - will be multiplied against the current attempt count inbetween attempts to - connect to redis. (Default `500 ms`) -- `TALK_REDIS_RECONNECTION_BACKOFF_MINIMUM_TIME` (_optional_) - the minimum time - used to delay before attempting to reconnect to redis. (Default `1 sec`) -- `TALK_REDIS_CLUSTER_MODE` (_optional_) - the cluster mode of the redis client. - Can be either `NONE` or `CLUSTER`. (Default `NONE`) -- `TALK_REDIS_CLUSTER_CONFIGURATION` (_optional_) - the json serialized form of - the cluster nodes. Only required when `TALK_REDIS_CLUSTER_MODE=CLUSTER`. See - https://github.com/luin/ioredis#cluster for configuration details. - (Default `[]`) - -### Server - -- `TALK_ROOT_URL` (*required*) - root url of the installed application externally - available in the format: `://:/`. -- `TALK_KEEP_ALIVE` (_optional_) - The keepalive timeout that should be used to - send keep alive messages through the websocket to keep the socket alive. (Default `30s`) -- `TALK_INSTALL_LOCK` (_optional for dynamic setup_) - When `TRUE`, disables the dynamic setup endpoint. (Default `FALSE`) - -#### Advanced -{:.no_toc} - -- `TALK_ROOT_URL_MOUNT_PATH` (_optional_) - when set to `TRUE`, the routes will - be mounted onto the `` component of the `TALK_ROOT_URL`. You would - use this when your upstream proxy cannot strip the prefix from the url. - (Default `FALSE`) -- `TALK_WEBSOCKET_LIVE_URI` (_optional_) - used to override the location to - connect to the websocket endpoint to potentially another host. This should - be used when you need to route websocket requests out of your CDN in order to - serve traffic more efficiently for websockets. **Warning: if used without - managing the auth state manually, auth cannot be persisted, for further - information refer to the [Persistence Documentation]({{ "/docs/running/persistence/" | absolute_url }})** - (Default `${ssl ? 'ws' : 'wss'}://${location.host}${TALK_ROOT_URL_MOUNT_PATH}api/v1/live`) -- `TALK_STATIC_URI` (_optional_) - Used to set the uri where the static assets - should be served from. This is used when you want to upload the static assets - through your build process to a service like Google Cloud Storage or Amazon S3 - and you would then specify the CDN/Storage url. (Default `process.env.TALK_ROOT_URL`) -- `TALK_DISABLE_STATIC_SERVER` (_optional_) - When `TRUE`, it will not mount the - static asset serving routes on the router. (Default `FALSE`) -- `TALK_HELMET_CONFIGURATION` (_optional_) - A JSON string representing the - configuration passed to the - [helmet](https://github.com/helmetjs/helmet) middleware. It can be used to - disable features like [HSTS](https://helmetjs.github.io/docs/hsts/) and others - by simply providing the configuration as detailed on the - [helmet README](https://github.com/helmetjs/helmet). (Default `{}`) - -### Word Filter - -- `TALK_DISABLE_AUTOFLAG_SUSPECT_WORDS` (_optional_) When `TRUE`, disables flagging of comments that match the suspect word filter. (Default `FALSE`) - -### JWT - -The following are configuration shared with every type of secret used. - -- `TALK_JWT_ALG` (_optional_) - the algorithm used to sign/verify JWT's used for - session management. Read up about alternative algorithms on the - [jsonwebtoken](https://www.npmjs.com/package/jsonwebtoken#algorithms-supported) package. (Default `HS256`) -- `TALK_JWT_EXPIRY` (_optional_) - the expiry duration (`exp`) for the tokens - issued for logged in sessions. (Default `1 day`) -- `TALK_JWT_ISSUER` (_optional_) - the issuer (`iss`) claim for login JWT - tokens. (Default `process.env.TALK_ROOT_URL`) -- `TALK_JWT_AUDIENCE` (_optional_) - the audience (`aud`) claim for login JWT - tokens. (Default `talk`) - -**You must also specify secrets as either the `TALK_JWT_SECRET` or the `TALK_JWT_SECRETS` -variable. Refer to the [Secrets Documentation]({{ "/docs/running/secrets/" | absolute_url }}) -on the contents of those variables.** - -#### Advanced -{:.no_toc} - -These are advanced settings for fine tuning the auth integration, and -is not needed in most situations. - -- `TALK_JWT_COOKIE_NAME` (_optional_) - the default cookie name to check for a - valid JWT token to use for verifying a user. (Default `authorization`) -- `TALK_JWT_SIGNING_COOKIE_NAME` (_optional_) - the default cookie name that is - use to set a cookie containing a JWT that was issued by Talk. - (Default `process.env.TALK_JWT_COOKIE_NAME`) -- `TALK_JWT_COOKIE_NAMES` (_optional_) - the different cookie names to check for - a JWT token in, separated by `,`. By default, we always use the - `process.env.TALK_JWT_COOKIE_NAME` and `process.env.TALK_JWT_SIGNING_COOKIE_NAME` - for this value. Any additional cookie names specified here will be appended to - the list of cookie names to inspect. -- `TALK_JWT_CLEAR_COOKIE_LOGOUT` (_optional_) - when `FALSE`, Talk will not - clear the cookie with name `TALK_JWT_COOKIE_NAME` when logging out (Default - `TRUE`) -- `TALK_JWT_DISABLE_AUDIENCE` (_optional_) - when `TRUE`, Talk will not verify or sign JWT's - with an audience (`aud`) claim, even if the `TALK_JWT_AUDIENCE` config is set. (Default `FALSE`) -- `TALK_JWT_DISABLE_ISSUER` (_optional_) - when `TRUE`, Talk will not verify or sign JWT's - with an issuer (`iss`) claim, even if the `TALK_JWT_ISSUER` config is set. (Default `FALSE`) -- `TALK_JWT_USER_ID_CLAIM` (_optional_) - specify the claim using dot notation for where the - user id should be stored/read to/from. Example `user.id` would store it like: `{user: {id}}` - on the claims object. (Default `sub`) - -When integrating with an external authentication system, the following JWT claims -will be used: - -```js -{ - "jti": "", // *required* unique id used for blacklisting - "aud": TALK_JWT_AUDIENCE, // *optional* if TALK_JWT_DISABLE_AUDIENCE === 'TRUE', *required* otherwise - "iss": TALK_JWT_ISSUER, // *optional* if TALK_JWT_DISABLE_ISSUER === 'TRUE', *required* otherwise - - [TALK_JWT_USER_ID_CLAIM]: "", // *required* the id of the user - // Note, if TALK_JWT_USER_ID_CLAIM contains '.', it will be used to delineate an object, for example - // `user.id` would store it like: `{user: {id}}` -} -``` - -When our passport middleware checks for JWT tokens, it searches in the following -order: - -1. Custom cookies named from the list in `TALK_JWT_COOKIE_NAMES`. -2. Default cookies named `TALK_JWT_COOKIE_NAME` then `TALK_JWT_SIGNING_COOKIE_NAME`. -3. Query parameter `?access_token={TOKEN}`. -4. Header: `Authorization: Bearer {TOKEN}`. - -### Email - -- `TALK_SMTP_EMAIL` (*required for email*) - the address to send emails from - using the SMTP provider. -- `TALK_SMTP_USERNAME` (*required for email*) - username of the SMTP provider - you are using. -- `TALK_SMTP_PASSWORD` (*required for email*) - password for the SMTP provider - you are using. -- `TALK_SMTP_HOST` (*required for email*) - SMTP host url with format - `smtp.domain.com`, note the lack of protocol on the domain. -- `TALK_SMTP_PORT` (*required for email*) - SMTP port. - - -### Recaptcha - -- `TALK_RECAPTCHA_SECRET` (*required for reCAPTCHA support*) - server secret used for enabling reCAPTCHA powered logins. If not provided it will instead default to providing only a time based lockout. -- `TALK_RECAPTCHA_PUBLIC` (*required for reCAPTCHA support*) - client secret used for enabling reCAPTCHA powered logins. If not provided it will instead default to providing only a time based lockout. - -### Trust - -Trust can auto-moderate comments based on user history. By specifying this -option, the behavior can be changed to offer different results. - -- `TRUST_THRESHOLDS` (_optional_) - configure the reliability thresholds for - flagging and commenting. (Default `comment:2,-1;flag:2,-1`) - -The form of the environment variable: - -``` -:,;:,;... -``` - -The default could be read as: - -- When a commenter has one comment rejected, their next comment must be - pre-moderated once in order to post freely again. If they instead get rejected - again, then they must have two of their comments approved in order to get - added back to the queue. -- At the moment of writing, behavior is not attached to the flagging - reliability, but it is recorded. - -### Cache - -- `TALK_CACHE_EXPIRY_COMMENT_COUNT` (_optional_) - configure the duration for which - comment counts are cached for. (Default `1hr`) - -### Plugins - -Plugins configuration can be found on the [Plugins]({{ "/docs/running/plugins/" | absolute_url }}) page. \ No newline at end of file diff --git a/docs/_docs/02-02-secrets.md b/docs/_docs/02-02-secrets.md deleted file mode 100644 index 42c1946b6..000000000 --- a/docs/_docs/02-02-secrets.md +++ /dev/null @@ -1,111 +0,0 @@ ---- -title: Secrets -permalink: /docs/running/secrets/ ---- - -{% include toc %} - -## Secret Types - -We support two types of secrets. - -- Shared secrets -- Asymmetric Secrets - -### Shared Secret - -You would use a shared secret when you have no need to share the tokens with -other applications in your organization. - -Supported signing algorithms: - -- HS256 -- HS384 -- HS512 - -These must be provided in the form: - -```json -{ - "secret": "" -} -``` - -### Asymmetric Secret - -You would use a asymmetric secret when you want to share the token in your -organization, and would like to pass an existing auth token to Talk in order to -authenticate your users. (Documentation on how to do this is pending!). - -Supported signing algorithms: - -- RS256 -- RS384 -- RS512 -- ES256 -- ES384 -- ES512 - -These must be provided in the form: - -```json -{ - "public": "", - "private": "" -} -``` - -Note that when using the asymmetric keys as discussed above, the certificates -must have their newlines replaced with `\\n`, this is to ensure that the -newlines are preserved after JSON decoding. Not doing so will result in parsing -errors. - -To assist with this process, we have developed a tool that can generate new -certificates that match our required format: [coralcert](https://github.com/coralproject/coralcert). -This tool can generate RSA and ECDSA certificates, check it's [README](https://github.com/coralproject/coralcert) -for more details. - -## Authentication Types - -Talk also supports two methods of providing authentication details. - -- Single key: this is used when your secrets do not need to be rotated. -- Multiple keys: this is used when you expect to rotate your secrets. - -### Single Key - -When using a single key, you can utilize the following configuration style: - -- `TALK_JWT_SECRET` (*required*) - The shared secret or certificate (depending - on your choice of `TALK_JWT_ALG`) used for jwt tokens. - -An example of this: - -```bash -# for a shared secret -TALK_JWT_SECRET={"secret": ""} - -# for a asymmetric secret -TALK_JWT_SECRET={"private": "", "public": ""} -``` - -### Multiple Key - -When using a multiple keys, you can utilize the following configuration style: - -- `TALK_JWT_SECRETS` (_optional_) - used when specifying multiple secrets used - for key rotations. This is a JSON encoded array, where each element matches - the JWT Secret pattern. - -All secrets also get a `kid` field which uniquely identifies a given key and -will sign all tokens with that `kid` for later identification. - -An example of this: - -```bash -# for a shared secret -TALK_JWT_SECRETS=[{"kid" "1", "secret": ""}, {"kid" "2", "secret": ""}] - -# for a asymmetric secret -TALK_JWT_SECRETS=[{"kid": "1", "private": "", "public": ""}, {"kid": "2", "private": "", "public": ""}] -``` \ No newline at end of file diff --git a/docs/_docs/02-03-plugins.md b/docs/_docs/02-03-plugins.md deleted file mode 100644 index e17f53f9e..000000000 --- a/docs/_docs/02-03-plugins.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: Plugins -permalink: /docs/running/plugins/ ---- - -Configuration for the available plugins are stored in a JSON encoded string. The format -of this document are available with the [Plugins Overview]({{ "/docs/plugins/" | absolute_url }}). - -You can override the plugin config by specifying the content in the `TALK_PLUGIN_JSON` -environment variable. - -## Bundled Plugin Configuration -{:.no_toc} - -Some of the core plugins that are bundled with Talk require specific configuration to be -available. - -{% include toc %} - -### Facebook Authentication - -- `TALK_FACEBOOK_APP_ID` (*required*) - the Facebook app id for your Facebook -Login enabled app. -- `TALK_FACEBOOK_APP_SECRET` (*required*) - the Facebook app secret for your -Facebook Login enabled app. \ No newline at end of file diff --git a/docs/_docs/02-04-migrations.md b/docs/_docs/02-04-migrations.md deleted file mode 100644 index 88afed842..000000000 --- a/docs/_docs/02-04-migrations.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: Database Migrations -permalink: /docs/running/migrations/ ---- - -On major version changes, database migrations are usually required. The -application will refuse to start until all pending migrations are ran. This also -applies to empty databases. - -## Running Migrations - -We have a migration tool that can be run using `bin/cli migration run`. This -will detect new migrations available and prompt you to backup your database -before proceeding with the migration. Migrations are required with major version -releases. \ No newline at end of file diff --git a/docs/_docs/02-05-persistence.md b/docs/_docs/02-05-persistence.md deleted file mode 100644 index a1d3a5e2f..000000000 --- a/docs/_docs/02-05-persistence.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: User Persistence -permalink: /docs/running/persistence/ ---- - -One of the biggest problems on the internet today is the proliferation of -sophisticated tracking systems and the outcome of invading user's privacy. This -has had quite a big impact on our design of Talk, as we've had to work around -the safeguards that are there to keep your data safe while still allowing our -application to run smoothly on the page it's embedded on. - ---- - -**Problem**: Safari has inconsistent behavior around localStorage when used -within an iFrame. - -**Solution**: We set a cookie instead when Safari is detected to store the auth -state. - ---- - -**Problem**: Safari's default privacy settings block cookies from domains that -do not match the current domain. - -**Solution**: When using Talk's built in auth, we will open a pop-out when -setting the cookie, so that the domain of the setting domain matches the issuer. - ---- - -**Problem**: When using a different domain for websockets, and using the built -in auth solution, cookies are not set on that domain for use with Safari. - -**No Solution Exists**: It is our expectation that for users that must deploy -Talk in environments that must run the websockets out of a separate domain will -use and integrate their own auth solution. During the login process in Talk, -users submit their user credentials to an auth endpoint, and receive a token -back, or for Safari, a cookie. Aggressive defaults in Safari make it not -possible to have one domain set cookies for another domain during this process. -This results in a situation where we have no way to persist the auth credentials -for this specific situation for the time being. - ---- - -If you are using a custom auth solution, (Which involves providing the user's -jwt token via the `auth_token` parameter on the call to -`Talk.render(... {auth_token})` and creating the -[tokenUserNotFound]({{ "/docs/plugins/server/" | absolute_url }}) hook to lookup -that user) then concerns related to cookies/localStorage are moot! As it isn't -necessary for Talk to maintain any state beyond what is passed to it via the -pym bridge. \ No newline at end of file diff --git a/docs/_docs/03-01-architecture.md b/docs/_docs/03-01-architecture.md deleted file mode 100644 index 493c7bb5f..000000000 --- a/docs/_docs/03-01-architecture.md +++ /dev/null @@ -1,77 +0,0 @@ ---- -title: Architecture Overview -permalink: /docs/architecture/ ---- - -## Talk's Architecture - -Talk consists of four distinct layers of code: - -* Plugins -* Plugin API -* Core -* cli - -### Plugins - -Talk plugins deliver the features and functionality that can be changed or removed. Much of the default functionality is delivered by core plugins allowing developers to have control over any non-essential functionality. - -### Plugin API - -Talk plugins interact exclusively with the Plugin API. Maintaining this layer of separation between plugins and core allows us to consciously design the api that we want it publish to plugin authors. We can then expose just the elements of core that make sense and maintain that contract as core changes. - -### Core - -Talk core consists of architecture and functionality that deliver stability, security, scalability, extendability, etc... In addition, the Core contains features and functionality that is essential to the operation of Talk as a product. - -Our goal is to continually extend our plugin infrastructure making the Core as pluggable as possible. Ultimately, a day may come where the Core of Talk is simply a framework for delivering a certain flavor of web applications. - -### cli - -Talk ships with [a cli tool]({{ "/docs/architecture/cli" | absolute_url }}) that exposes functionality to the command line. We seek to provide cli functionality for all features that could need to be accomplished programmatically or prior to the server's startup. - -## Thinking about Plugins, the Plugin API and Core? - -The following is a template for a thought process that may help clarify your ideas against the backdrop of Talk's architecture. - -Think of a feature or capability. It could be something that's already in Talk or not. It could be something you want to build, or something you'd think would be a terrible idea. The important part here is to have something to interrogate. - -``` -wait(60000); -``` - -Now, ask these questions: - -### Is it a Plugin? - -Most work for Talk happens in the Plugin space. If the answers to any of these questions is Yes, then you're thinking of a Plugin. - -* Does Talk's existing Plugin APIs support the thing you want to build? -* Is this something that only some users will want/need? -* Is this something that we want devs to iterate on widely? - -You should [build it as a plugin]({{ "/docs/plugins/quickstart" | absolute_url }}). Feel free to explore here on your own or reach out to us. We love to advise on plugins, so please feel free to [let us know]({{ "/docs/development/contributing" | absolute_url }}#writing-code) and we will start a conversation. We will help you conceptualize, architect and promote your plugin if it is in line with our values. - -### Does it need updates to the Plugin API? - -If you answered yes above: - -* Do I need to extend the Plugin API to support my plugin? - -Often times all the functionality a plugin needs is in the Core, but the Plugin API doesn't expose it. In these cases, we seek to iteratively extend the Talk Plugin API. All Plugin API contributions from the community must begin by [let us know]({{ "/docs/development/contributing" | absolute_url }}#writing-code). - -Note: we are stabilizing the process by which new Plugin API bindings are created, agreed upon and ultimately made part of our Plugins Contract. If you are interested in this process, please reach out to us. - -### Does it require updates to the Plugin API _and_ Core? - -What, if any, changes need to be made to Core so that the API can be extended? - -Quite often the only things missing from Core are things like _events_, _slots_, _CSS classes_, etc... Adding these is a great way to become a Core Contributor and break new ground as a Plugin Developer. - -We seek to keep Core as lean as possible. - -### Is my idea really just Core? - -Amazing! We are always looking to extend the capabilities of Talk. We look forward to discussing what you've got to bring! - -Please see our [contributing guide]({{ "/docs/development/contributing" | absolute_url }}) for more information. diff --git a/docs/_docs/03-02-architecture-tags.md b/docs/_docs/03-02-architecture-tags.md deleted file mode 100644 index 1b2218cae..000000000 --- a/docs/_docs/03-02-architecture-tags.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: Tags -permalink: /docs/architecture/tags/ ---- - -Tags are essentially strings that can be added to models. Currently, tags can be added to [Users, Comments and Assets](https://github.com/coralproject/talk/blob/ced449a1489d47c25d604020fa2e0b3b7a741353/graph/typeDefs.graphql#L144). If you would like to add tags to other models, you can extend this schema using [GraphQL hooks]({{ "/docs/plugins/server" | absolute_url }}#graphql-hooks). - -## Tag Definitions - -When handling tags, the Talk Server references a set of definitions that describe how tags are handled. These definitions are keyed off the tag `name`, the simple string that is stored on items. - -The schema for Tag definitions [can be found here](https://github.com/coralproject/talk/blob/3545bf01cd91044fdb738d337a0ac94d9f71fbc3/models/schema/tag.js). - -Note that along with the `name`, tag definitions contains: - -* `permissions` information about who can see and set the tag, -* `models` which `ITEM_TYPES` this tag can be applied to, and - -Whenever a tag is 'handled' by the server, it references this definition to determine that tag's behavior. - -See [Plugin API Documentation]({{ "/docs/plugins/server" | absolute_url }}#field-tags) for more information. - -### Creating a Tag Definition - -Tag Definitions must be created in order for the system to determine what tags are permitted on the server side. - -Tag Definitions do not contain any logic themselves but provide information that other parts of the system can use to specify which models a tag can be applied to (models) and perform authorization logic (permissions). - -Take the tag created by `talk-plugin-offtopic` as an example. - -``` -// talk-plugin-offtopic/index.js -module.exports = { - tags: [ - { - name: 'OFF_TOPIC', - permissions: { - public: true, - self: true, - roles: [] - }, - models: ['COMMENTS'], - created_at: new Date() - } - ] -}; -``` - -This plugin allows users to self-report that their comment is "off topic" at the time of creation, then display a badge on those comments. - -To accomplish this, the plugin creates the tag `OFF_TOPIC` with: - -* `permissions.public: true` - will be sent over the wire to the client side -* `permissions.self: true` - can be added by the active user to themselves or assets they own -* `permissions.roles: []` - cannot be added by anyone based on their roles -* `models: ['COMMENTS']` - can only be added to COMMENTS (not to users/assets/etc...) - -And [viola](https://youtu.be/Q0O9gFf-tiI?t=23s)! This tag is something that can only be created by the logged in user on their own comments and is sent over the wire to the client so it can display the badge. - -## Tag Links - -When tags are stored on objects in the database, they are represented by [TagLinks](https://github.com/coralproject/talk/blob/master/models/schema/tag_link.js). - -A TagLinks says that `tag` was `assigned_by` a specific user at a specific time (`created_at`). - -Note that the `tag` field in the TagLinkSchema is the full TagSchema itself. This allows for another level of flexibility. Server code may generate Tags on the fly, complete with programmatically generated permissions and item behaviors. - -If a Tag definitions exists in the global/asset context then that definition will be used regardless of what is stored here. This allows high level controls on the behavior of tags, ensuring that plugins cannot produce unexpected definitions for already defined tags. diff --git a/docs/_docs/03-03-architecture-metadata.md b/docs/_docs/03-03-architecture-metadata.md deleted file mode 100644 index db71ce047..000000000 --- a/docs/_docs/03-03-architecture-metadata.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: Metadata -permalink: /docs/architecture/metadata/ ---- - -_Metadata_ allows you to add fields to models that are not represented in the core schema. - -## Goals - -The metadata api is designed to satisfy two product goals: - -* Give developers flexibility in extending datatypes. -* Protect core fields that are essential to Talk's operation. - -## Design - -Metadata is represented by an [subdocument in our Schemas](https://github.com/coralproject/talk/blob/c59c09e1f42c51eed3b0d57b7c2882fc7b5edc13/models/comment.js#L74). This takes advantage of Mongo's flexibility allowing for any data to be stored therein. - -### Setting Metadata - -Talk provides [a service layer](https://github.com/coralproject/talk/blob/c59c09e1f42c51eed3b0d57b7c2882fc7b5edc13/services/metadata.js) allowing developers to `set` and `unset` metadata on objects in a way similar to key-value stores. - -Let's say that I want to add a custom field called `potency` to a comment. - -``` -const MetadataService = require('services/metadata'); -const CommentModel = require('models/comment'); - -// Sets the property `potency` on the comment with `id=1`. -MetadataService.set(CommentModel, '1', 'potency', 42); -``` - -Note that the model passed here is the Model itself and not an individual comment object. This allows us to update the value on that document [in an atomic manner](https://github.com/coralproject/talk/blob/c59c09e1f42c51eed3b0d57b7c2882fc7b5edc13/services/metadata.js#L60) for efficiency and to prevent race conditions. - -### Accessing Metadata - -The metadata api does not contain a `get` method. The metadata object is retrieved via database queries along with the rest of the data. - -## Metadata and the Graph - -One of the first principles of GraphQL is that the shape of the graph does not need to be the same as the shape of the data in the database. In fact, it probably shouldn't be. - -This enables us to treat metadata fields in any way that makes sense as we design our Graph. The fact that a value is stored in the metadata object is an implementation detail invisible to the front end. - -Take for example, the `reason` field in the `FlagAction` type. This stores the user provided reason why they flagged a comment. As far as the front end knows, it's [just another field](https://github.com/coralproject/talk/blob/c59c09e1f42c51eed3b0d57b7c2882fc7b5edc13/graph/typeDefs.graphql#L453) alongside the core fields: - -``` -# graph/typeDefs.graphql -type FlagAction implements Action { - - ... - - # The reason for which the Flag Action was created. - reason: String - - ... -} -``` - -If, however, we [look at the resolver](https://github.com/coralproject/talk/blob/a47e2378e96f34f25447782f3e7ce59fa48ec791/graph/resolvers/dont_agree_action.js) for that field, we see that `reason` is [destructured](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) from the metadata object and returned. - -``` -// graph/resolvers/dont_agree_action.js -const DontAgreeAction = { - - // Stored in the metadata, extract and return. - reason({metadata: {reason}}) { - return reason; - } -}; - -module.exports = DontAgreeAction; -``` - -This is an extremely powerful pattern as it allows us absolute freedom in designing our graph and complete isolation of the added fields in the database. - -## Some things to keep in mind - -### Namespace your metadata fields - -Since metadata can be added by the core and multiple plugins, collisions may occur. As you create your plugins, please be careful to pick unique names for metadata fields. We recommend namespacing all your fields in a subdocument named after your plugin. - -``` -[model].metadata.[your_plugin_name].[the_field] -``` - -### Querying by metadata fields - -We currently do not have a clean way to index metadata fields. As a result queries that match against metadata fields will not scale. If you have a need to match, sort, etc... by a metadata field, [please let us know]({{ "/docs/development/contributing" | absolute_url }}#writing-code). diff --git a/docs/_docs/03-04-architecture-cli.md b/docs/_docs/03-04-architecture-cli.md deleted file mode 100644 index 0a61917f9..000000000 --- a/docs/_docs/03-04-architecture-cli.md +++ /dev/null @@ -1,136 +0,0 @@ ---- -title: Command Line Interface (cli) -permalink: /docs/architecture/cli/ ---- - -Talk ships with a cli tool that allows access to a wide variety of functionality. - -It is designed to provide a convenient way for engineers to perform key tasks without the need to muck about in the UI. It also opens the door for scripts to perform operations programmatically. - -Note: the cli tool requires [the Talk environment to be configured]({{ "/docs/running/configuration" | absolute_url }}) either via env vars or by using a `.cli` file via `bin/cli -c .env [command] ....` - -## Using the cli - -In a terminal, try: - -``` -/path/to/talk/bin cli [options] [commands] [arguments] -``` - -Commonly, you'll be in the `talk/` folder, in which case you can: - -``` -bin/cli [options] [commands] [arguments] -``` - -If you're a heavy cli user, consider adding the `bin` folder to your PATH so you can run `cli` from anywhere! - -If you are using [our Docker environment]({{ "/docs/install/docker" | absolute_url }}), the bin folder will already be in the PATH. - -## What can I do with the cli? - -The Talk cli ships with 'unix style' help. To access the docs, simply run the cli with insufficient arguments. - -Let's say I wanted to figure out how to change a user's password. I'd start be seeing what the cli has for me. - -(Note: the following output may change, please reference at the `--help` output for your version as you use the cli.) - -``` -talk :) ]$ bin/cli --help - - Usage: cli [options] [command] - - - Commands: - - serve serve the application - settings interact with the application settings - assets interact with assets - setup setup the application - jobs work with the job queues - token work with the access tokens - users work with the application auth - migration provides utilities for migrating the database - plugins provides utilities for interacting with the plugin system - help [cmd] display help for [cmd] - - Options: - - -h, --help output usage information - -V, --version output the version number - -c, --config [path] Specify the configuration file to load - --pid [path] Specify a path to output the current PID to -``` - -Most commands contain sub-commands. Running with cli with such a command generates the docs for the sub-commands and options therein. - -Change user password is likely to be in the `users` command group. - -``` -talk :) ]$ bin/cli users - - Usage: cli-users [options] [command] - - - Commands: - - create [options] create a new user - delete delete a user - passwd change a password for a user - update [options] update a user - list list all the users in the database - merge merge srcUser into the dstUser - addrole adds a role to a given user - removerole removes a role from a given user - ban ban a given user - uban unban a given user - disable disable a given user from logging in - enable enable a given user from logging in - - Options: - - -h, --help output usage information - -V, --version output the version number - -c, --config [path] Specify the configuration file to load - --pid [path] Specify a path to output the current PID to -``` - -I now see that I can change a password like so: - -``` -bin/cli users passwd [userID] -``` - -You can also read these help prompts by [exploring the source code](https://github.com/coralproject/talk/blob/master/bin/cli). - -### Usage Notes - -If you haven't used a cli enabled system before, think of it like this: generally, you'd make a rest call, rpc, etc... to perform an action. The cli's api is designed in the same way, just for the audience of command line wielding engineers and scripts. - -The best way to understand what the cli does is to explore the help commands. Uses of cli are also scattered through this documentation in context of their topics. - -For some real world uses of the cli, see the scripts in the [package.json file](https://github.com/coralproject/talk/blob/d688f70c19d8dee48371784009fd07322dae4eb5/package.json#L8). - -## What's really going on when I run the cli? - -The cli tool is a standalone application. Running it starts up the internals of a talk process, executes the given command, then shuts it down. No server functionality is enabled by cli commands unless specifically noted. - -The cli tool _does not require a talk server to be running._ This means that you can execute commands, for example, during and installation process before starting the server. The also means that you can execute commands using varying configurations (via the `-c [.env file]` flag). - -### Accessing existing Talk installs with the cli - -You may use the cli tool to 'remotely' control existing talk installs. - -This is accomplished by running the cli tool on any box using the mongo/redis/etc... credentials for the environment that you would like to act on. For example, if you want something to happen periodically on your production Talk install, you could set up a utility box with a cron job that triggers the cli with the same db/cache credentials. If you want to do something quick on a staging server, you could run the cli locally with staging credentials. - -The cli tool will connect directly with the install's db and redis instance(s) so ensure that your box can reach those servers on the appropriate ports. - -Also, _please ensure your cli and the server(s) in an environment are using the same version of Talk._ - -Please secure your environments and credentials or the cli tool becomes a convenient way for someone to own your system. - -## Extending the cli - -The Talk cli is based on the excellent [commander](https://github.com/tj/commander.js/) library. - -At the time of writing, there are no plugin hooks for the cli tool. If you would like to change this, whether by writing code yourself or recommending a need, please [write and issue]({{ "/docs/development/contributing" | absolute_url }}#writing-code). diff --git a/docs/_docs/03-05-client-architecture.md b/docs/_docs/03-05-client-architecture.md deleted file mode 100644 index f102573f2..000000000 --- a/docs/_docs/03-05-client-architecture.md +++ /dev/null @@ -1,117 +0,0 @@ ---- -title: Client Architecture -permalink: /docs/architecture/client ---- - -## The Stack - - [React](#react) - - [Redux](#redux) - - -## The Architecture -Our frontend lives within [talk/client](https://github.com/coralproject/talk/tree/153193959cb4dfa5d8feaabb49811325f836ee68/client) folder. Every folder contains a plugin. In [coral-framework](https://github.com/coralproject/talk/tree/153193959cb4dfa5d8feaabb49811325f836ee68/client/coral-framework) you will find the core architecture of Talk. -Here is where our Redux Application, translations, components, and helpers live. - - -## Presentational and Container Components -We use a common simple pattern called -__Presentational and Container Components__ - -It basically consist in having two types of components: - - Presentational - - Containers - -### Presentational Components -- __How our UI looks like__ -- Are stateless components -- Render props -- Allow containment of children via `this.props.children` -- They have DOM Markup - -### Container Components -* __How things work__ -* They don’t have markup nor styles -* They provide data and behavior to Presentational or Container Components -* They connect via `react-redux`’s `connect()` to the state. -* They `mapStateToProps` the state to the Presentational Container. -* They `mapDispatchToProps` to send actions to the Presentational Container. -* Name Convention `Container.js` - -How a container looks like: -```js -/* -* mapStateToProps -* We map the part of the state that we want to use -*/ - -const mapStateToProps = state => ({ - auth: state.auth.toJS() -}); - -/* -* mapDispatchToProps -* We map the actions that we want to use -*/ - -const mapDispatchToProps = dispatch => ({ - checkLogin: () => dispatch(checkLogin()) -}); - - -/* -* connect -* We wrap our container in a connect() function -*/ - -export default connect( - mapStateToProps, - mapDispatchToProps -)(SignInContainer); -```` - -How our SignInContainer works: [talk/SignInContainer.js · GitHub](https://github.com/coralproject/talk/blob/153193959cb4dfa5d8feaabb49811325f836ee68/client/coral-sign-in/containers/SignInContainer.js) - -Within our plugins we create two folders `containers` and `components` so we can differentiate them: -``` -coral-sign-in/ -├── containers/ -│ └── SignInContainer.js -└── components/ - ├── SignInContent.js - └── SignUpContent.js -``` - -More about this architecture: - -[Container Components – Learn React with chantastic – Medium](https://medium.com/@learnreact/container-components-c0e67432e005#.w8mzgndcg) - - -[Presentational and Container Components – Dan Abramov – Medium](https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0#.ai4ih55v3) - - -## GraphQL -We use [Apollo](http://www.apollodata.com/) to handle graph requests and handle state. - -## Redux -We use [Redux](http://redux.js.org/) to handle the auth state. - -## Test -[How we do testing at Coral with Talk]({{ "/docs/development/tools" | absolute_url }}) - - -## Lint -For linting in Talk we use `eslint:recommended` - -You can find more info about the rules and best practices here: - -http://eslint.org/docs/rules/#best-practices - -## Lint the code -```js -yarn lint -``` - - -## The Future of the Frontend -- [Preact](https://github.com/developit/preact) -- [Reselect](https://github.com/reactjs/reselect) diff --git a/docs/_docs/04-02-plugins-quickstart.md b/docs/_docs/04-02-plugins-quickstart.md deleted file mode 100644 index ec5e23fef..000000000 --- a/docs/_docs/04-02-plugins-quickstart.md +++ /dev/null @@ -1,241 +0,0 @@ ---- -title: Plugins Quickstart -permalink: /docs/plugins/quickstart/ ---- - -This tutorial walks through the mechanics of creating and publishing a Talk plugin. Along the way I call out some particular habits and techniques that I employ. If you have other practices that you find valuable, please don't hesitate to [contribute!]({{ "/docs/faq" | absolute_url }}#how-do-i-contribute-to-these-docs) - -We will create a plugin that exposes a route that allows assets to be created or updated. - -## Setup the environment - -Before I begin working on the plugin, I've installed [Talk from source]({{ "/docs/development/tools" | absolute_url }}). - -### Watch the Server - -In a terminal, I run `yarn dev-start`. This: - -* starts my server, showing plugin and configuration information -* restarts it when I save files -* shows my temporary `console.log()` statements -* shows real time access logs -* shows verbose debug output if enabled (more on this later) - -### Watch the Client build process - -In a separate terminal I run `yarn build-watch`. This: - -* builds the client side javascript bundles -* watches relevant files and rebuilds the bundle on change -* displays _compile time_ errors, including (the many) syntax errors I cause - -If you need to run `yarn install`, you will see missing module error messages here. - -### Watch from the Browser - -I open up `http://localhost:3000` in a web browser and see the default comment stream. I then open the dev tools console, which: - -* shows any _run time_ errors/warnings generated on the front end. -* shows any temporary `console.log()` statements I add during development. - -I also often toggle to the Network Tab to see: - -* which files are being loaded -* requests sent from my front end code, including headers, the payload/queries sent and the data returned - -I strongly recommend taking the time to fully explore all the features of your browser's dev tools! - -## Create a home for my new plugin - -My goals for this tutorial are to: - -* build this plugin locally -* use source control and publish for collaboration -* publish the plugin as an npm library - -### Create a repo - -I create a new repo called `talk-plugin-asset-manager`. (I use github, but this you could store this anywhere, bitbucket, svn, etc...) - -_make sure to respect the naming convention `talk-plugin-*`. This will allow for easy identification of the repo and, eventually, easy searching on npm._ - -### Set up a local file structure - -In a blatant rip off from the Golang community, I create an environment var to hold the path to the root of my Coral directory. This allows absolute pathing. - -``` -export CORALPATH=/path/to/my/coral/root/dir -``` - -I like to put my plugins in a directory next to talk, but you could put this anywhere. - -``` -cd $CORALPATH -git clone https://github.com/jde/talk-plugin-asset-manager.git -``` - -### Register your plugin - -Add the plugin to the plugins.json file: - -```json -{ - "server": [ - ... - "talk-plugin-asset-manager" - ], - "client": [ - ... - // no client side components so I won't add it here - ] -} -``` - -But wait! Talk looks in `talk/plugins/[plugin-name]` for plugin code. Why couldn't we just add that plugin there? - -We could have. - -This would make it _a little_ easier to register, but _a lot_ harder to cleanly manage in version control. In order to avoid it being sucked into your Talk repo, you would have to manually `.gitignore` it or use sub modules or something similar. - -As a user of a Linux_y_ os, I prefer to create a symbolic link. - -```bash -cd $CORALPATH/talk/plugins -ln -s $CORALPATH/talk-plugin-asset-manager -``` - -Now, as far as Talk knows, our plugin is right there in the folder. Git is wise, however, and will not include it in the Talk repo. Best of all, our `yarn dev-start` based watch statement follows symbolic links and will restart our sever each time a file is saved. - -### Create the initial index file - -All plugins contain server and/or client index files, which export all plugin functionality. - -```js -// talk-plugin-asset-manager/index.js -module.exports = {}; -``` - -## Build the feature! - -Now that the plugin is set up I can get down to writing the feature. My goal is to allow my CMS to push new assets as they are created into Talk. To accomplish this, I will create a POST endpoint using Talk's [route api]({{ "/docs/plugins/server" | absolute_url }}#field-router). - -### Create a route - -When designing my api, I want to be careful to avoid conflicts with not only the existing Talk api, but other plugins in the open source ecosystem that may be creating routes. To do this, I'll follow the golden rule of creating universals with plugins: - -_Always namespace all universals with your plugin's unique name._ - -To ensure everything is hooked up, I'll log the request body (POST payload in this case) to the console and echo it as the response: - -```js -// talk-plugin-asset-manager/index.js -module.exports = { - router(router) { - router.post('/api/v1/asset-manager', (req, res) => { - console.log(req.body); - res.json(req.body); - }); - } -} -``` - -When I save this file, I reflexively check my console to be sure that the server restarts. - -To test that this works, I can: - -```bash -$ curl -H "Content-Type: application/json" -X POST -d '{"url":"http://localhost:3000/my-article","title":"My Article"}' http://localhost:3000/api/v1/asset-manager -{"url":"http://localhost:3000/my-article","title":"My Article"} -``` - -After hitting the endpoint, I can also look at the terminal running `yarn dev-start` and see my `console.log()` and the access log: - -``` -{ url: 'http://localhost:3000/my-article', - title: 'My Article' } -POST /api/v1/asset-manager 200 1.379 ms - 68 -``` - -### Save the asset - -When I save this asset, I will use Talk's [asset model](https://github.com/coralproject/talk/blob/master/models/asset.js). - -Mongo has a handy method [findOneAndUpdate](https://docs.mongodb.com/v3.2/reference/method/db.collection.findOneAndUpdate/) that will take care determining whether or not this asset exists, then either updating or inserting it. Whenever possible, we recommend using these atomic patterns that prevent multiple queries to the db and the efficiency problems and race conditions that they cause. - -```js -// talk-plugin-asset-manager/index.js - -const AssetModel = require('models/asset'); - -module.exports = { - router(router) { - router.post('/api/v1/asset-manager', (req, res) => { - - const asset = req.body; - const update = {$setOnInsert: {url: asset.url}}; - - AssetModel.findOneAndUpdate(asset, update, { - new: true, - upsert: true, - setDefaultsOnInsert: true - }) - .then((asset) => res.json(asset)); - }); - } -} -``` - -I can now run the `curl` command as before and see that the response contains a complete asset document! - -In addition, I can change the title in the json payload and verify that the id is the same, indicating that the record was updated! - -Lastly, I can see the asset in the admin panel at `http://localhost:3000/admin` as well as in my database. - -We have an alpha version of our plugin! - -### More work to be done - -The purpose of this tutorial is to follow the full lifecycle of a plugin, from conception through publication into deployment. With that in mind we'll move forward with this alpha version. - -Some things to make this production ready: - -* refactoring to separate concerns -* commenting -* adding tests -* validating data -* [adding security](https://github.com/coralproject/talk/blob/b805451d376d2892c81c58d8822a85563e469b88/routes/api/users/index.js#L14) -* incorporating [domain whitelisting](https://github.com/coralproject/talk/blob/b805451d376d2892c81c58d8822a85563e469b88/services/assets.js#L60). - -It is important to realize that when you're writing a Talk plugin you are writing a program that may be touched by other devs and could grow in size and complexity. Bring your best engineering sensibilities to bear. - -## Publishing the plugin - -### Publish to npm - -In order to [register]({{ "/docs/plugins" | absolute_url }}#plugin-registration) your _published_ plugin, you will need to [publish it to npm](https://docs.npmjs.com/getting-started/publishing-npm-packages). - -Once the package is published, update `plugins.json` to use the published plugin: - -```json -{ - "server": [ - // ... - {"talk-plugin-asset-manager": "^0.1"} - ], - // ... -} -``` - -Finally, run the `reconcile` script to install the plugin from npm. - -```bash -$ bin/cli plugins reconcile -``` - -Once you've taken this step, anyone can register your plugin into their Talk server! Thank you for contributing to the open source community! - -### Publish to version control - -This plugin is open source, so I'm also going to [publish it to github](https://github.com/jde/talk-plugin-asset-manager/commit/66b626caa85cb8030b3ddaa7c1a4821bf01e350a) and [cut a release](https://github.com/jde/talk-plugin-asset-manager/releases/tag/v0.1) that mirrors the npm release. - -## Done! diff --git a/docs/_docs/04-03-plugins-client.md b/docs/_docs/04-03-plugins-client.md deleted file mode 100644 index 511ccde6c..000000000 --- a/docs/_docs/04-03-plugins-client.md +++ /dev/null @@ -1,331 +0,0 @@ ---- -title: Client Plugin API -permalink: /docs/plugins/client/ ---- - -{% include toc title="API" %} - -## Overview - -We can build plugins to extend the client side functionality of Talk. - -The ultimate goal of our client side plugin architecture is to allow developers -to build on existing concepts without needing to understand core code while -providing complete power and flexibility of javascript, css and html. - -* [Plugin Architecture](#plugin-architecture) -* Using our building block components -* [Reactions](#reactions) -* [Styling](#styling-plugins) - -Advanced users will quickly realize that our plugins have complete access to core code. If you would like to write advanced plugins that reach outside of our published API as described in this document, please see [our notes on experimental plugins]({{ "/docs/plugins/experimental/" | absolute_url }}). - -Under the hood our plugins are powered by *React*, *Redux* and *GraphQL*. We can also build them with simple vanilla javascript. - -## Plugin Architecture - -The plugins live in the `/plugins` folder. Each plugin must have an `index.js` file and two folders `client` and `server`. - -### The Client Folder -The frontend of our plugin lives inside the `client` folder. The `client` folder must have an `index.js` file that exports the configuration of our plugin. - -``` -my-plugin/ - ├── client/ - │ └── index.js <-- index for client side functionality - ├── server/ - └── index.js <-- base plugin index -``` - -For now our base plugin `index.js` file should look like this: - -```js -export default { - // We will add more here later. -}; -``` - -### Creating a Component - -We can add our components (or any other javascript code) within the `client` folder. - -``` -my-plugin/ - ├── client/ - │ ├── MyComponent.js - │ └── index.js - ├── server/ - └── index.js -``` - -Our component could look like this: - -```js -import React, {Component} from 'react'; - -class MyButton extends Component { - render() { - return ; - } -} - -export default MyButton; -``` - -Here we create a component that renders a `button`. Now that we created our component we need to specify where it should get injected within Talk! - -To tell Talk where that Component should get injected we need to specify which *Slots* to insert it into. - -```js -import React from 'react'; -export default = () => ; -``` - -### Slots -In Talk we have defined specific *Slots* where we can inject components. - -Here is how we specify our slots config in `my-plugin/index.js` - -```js -import MyButton from './MyButton'; - -export default { - slots: { - commentDetail: [MyButton] - } -}; -``` - -Here I’m specifying that the MyComponent Component will take place within the `commentDetail` in Talk. - -`commentDetail` it’s a specific slot in the CommentStream. It means that it will be embedded inside de comment detail. - -Slots properties take an`Array` so we can add as many components as we want. - -## Building Blocks (TBD) - -`Note: the concepts in this section are still to be implemented. Code samples are for discussion and may change.` - -In order to allow you to build more complex plugins, we have wrapped some of our functionality in higher order components that expose a simple api. - -## Reactions - -Reactions provide users the ability to 'like', 'respect', etc... comments. - -Note: some server side work will need to accompany this client side component. See the like and respect plugins as examples. - -### Building Reactions - -#### Our `client/index.js` : - -```js -import LoveButton from './LoveButton'; - -export default { - slots: { - commentReactions: [LoveButton] - } -}; - -``` -In this example we add our reaction component to the `commentReaction` Slot - -#### Our Reaction component: - -```js -import React from 'react'; -import {withReaction} from 'talk-plugin-api'; - -class LoveButton extends React.Component { - handleClick = () => { - const { - postReaction, - deleteReaction, - alreadyReacted - } = this.props; - - if (alreadyReacted()) { - deleteReaction(); - } else { - postReaction(); - } - }; - - render() { - const {count} = this.props; - return ( - - ); - } -} - -export default withReaction('love')(LoveButton); -``` - - -This feature introduces `withReaction` HOC. `withReaction` takes, as argument, a reaction string and it allows our component to receive specific props for handling reactions. - - * `postReaction` - Posts the reaction - - * `deleteReaction` - Removes the reaction - - * `alreadyReacted` - A function that returns a boolean. - - * `count` - The reaction count - - -For full reference: Please, check `talk-plugin-love`: [LoveButton.js](https://github.com/coralproject/talk/blob/master/plugins/talk-plugin-love/client/LoveButton.js) - -### Comment Stream - -Comment streams may be created with filtering and ordering in place: - -* filter by user -* filter by tag -* sort by date ascending / descending - -### Comment Commit hooks - -// docs for the pre/post comment submit commit hooks - -### Mod Queues - -Moderation queues can be added via configuration objects passed in through plugins. - -Basic mod queues will resemble the current moderation queues but can be generated from different lists of comments. - -* filter by user tag -* filter by comment tag -* filter by comment status -* Custom queries (paired with back end plugins that provide queries to get the data) - -#### Advanced mod queues - -Advanced mod queues can be created giving plugin authors the power to create the cards that appear in the queue, create actions and custom buttons, etc... - -### Custom Configuration - -Plugins may rely on configuration options that admins/moderators can set in the Configuration section. - -Basic settings can be added via json configuration in a plugin. - -* Setting headline -* Setting description -* Setting input type -* Default value -* Variable name - -#### Advanced Custom Configuration (low priority) - -Users can inject configuration interfaces that they create into the configuration allowing for more advanced configuration. - - -## Styling Plugins -Talk uses CSS Modules. This basically means that you can also add your CSS Module to your plugin without colliding with the rest of Talk! - -##### My Component -```js -import styles from './style.css'; - -class MyCoralButton extends Component { - render() { - return ; - } -} -```` - -Our `style.css` should could look like this. -```css - -.button { - background: coral; - border-radius: 3px; -} -``` - -## Plugin Hooks -The plugins injected in the CommentBox such as `commentInputDetailArea` will inherit through props tools for handling hooks. - -### Available hook types: -`preSubmit` : To perform actions before submitting the comment. -`postSubmit` : To perform actions after submitting the comment. - -### Register Hooks -`registerHook` is a function that takes: the hook type, a hook function and returns the hook data. - -#### Usage: -```js - this.addCommentTagHook = this.props.registerHook('postSubmit', (data) => { - const {comment} = data.createComment; - this.props.addCommentTag({ - id: comment.id, - tag: 'OFF_TOPIC' - }); - }); -``` - -### Unregister Hooks - -`unregisterHook` will remove the hook. - -```js - this.props.unregisterHook(this.addCommentTagHook); -``` - -### The server folder and the index file - -Read more about the `/server` and how to extend Talk here. - -[Server API]({{ "/docs/plugins/server/" | absolute_url }}) - -## ESlint and Babel -In talk we use `eslint:recommended` and Babel with the latest ECMAScript Features. But you can use your own! -While building your plugin you need to specify a `.eslintrc.json` file and a`.babelrc` file. - -### `.eslintrc.json` -```json -{ - "env": { - "browser": true, - "es6": true, - "mocha": true - }, - "parserOptions": { - "sourceType": "module", - "ecmaFeatures": { - "experimentalObjectRestSpread": true, - "jsx": true - } - }, - "parser": "babel-eslint", - "plugins": [ - "react" - ], - "rules": { - "react/jsx-uses-react": "error", - "react/jsx-uses-vars": "error", - "no-console": ["warn", { "allow": ["warn", "error"] }] - } -} -``` - -### `.babelrc ` -```json -{ - "presets": [ - "es2015" - ], - "plugins": [ - "add-module-exports", - "transform-class-properties", - "transform-decorators-legacy", - "transform-object-assign", - "transform-object-rest-spread", - "transform-async-to-generator", - "transform-react-jsx" - ] -} -``` diff --git a/docs/_docs/04-04-plugins-server.md b/docs/_docs/04-04-plugins-server.md deleted file mode 100644 index e639cd308..000000000 --- a/docs/_docs/04-04-plugins-server.md +++ /dev/null @@ -1,494 +0,0 @@ ---- -title: Server Plugin API -permalink: /docs/plugins/server/ ---- - -{% include toc title="API" %} - -## The Server Folder -The server functionality of our plugin lives inside the `server` folder. The `server` -folder must have an `index.js` file that exports the configuration of our plugin. - -``` -my-plugin/ - ├── client/ - │ └── ... <-- client side plugin files - ├── server/ - │ └── index.js <-- index for server side functionality - │ └── ... <-- other server side plugin files - └── index.js <-- base plugin index -``` - -## Specification - -Each plugin should export a single object with all hooks available on it. - -_**Note: You will have access to the whole core and other plugin's typeDefs, -context, loaders, mutators, resolvers, hooks. This is intentional, as it -encourages composing plugins to merge functionality, like a Slack plugin which -provides a Slack notify context function as well as having the loader for -comments.**_ - -The following are the hooks available: - -### GraphQL hooks - -#### Field: `typeDefs` - -```graphql -enum COLOUR { - RED - BLUE -} - -type Person { - name: String! - colour: COLOUR! -} - -type RootMutation { - createPerson(name: String!): Person -} - -type RootQuery { - people: [Person!] -} - -type Subscription { - leader: Person -} -``` - -Thanks to [gql-merge](https://www.npmjs.com/package/gql-merge) the contents of -`typeDefs` should be a string that will be _merged_ with the existing type -definitions. `enum`'s will be appended to, types will be appended, and new types -will be added. - -#### Field: `context` - -```js -{ - Slack: (context) => ({ - notify: (message) => { - // return a promise after we're done sending notifications. - } - }) -} -``` - -Any property provided here will be added to the context parameter available -inside all resolvers, loaders, mutators, and of course, other context based -plugins. - -The top level item must accept a context for the request which it should use to -configure the context plugin before it would be mounted at `context.plugins`. -This plugin above would mount at: `context.plugins.Slack`, or, if you're using -[object destructuring](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment), `{plugins: {Slack}}`. - -##### Field: `Sort` - -A special context hook, `Sort` will allow plugin authors to provide new -methods to sort data. An example is as follows: - -```js -{ - Sort: () => ({ - Comments: { // <-- (1) - likes: { // <-- (2) - startCursor(ctx, nodes, {cursor}) { // <-- (3) - return cursor != null ? cursor : 0; - }, - endCursor(ctx, nodes, {cursor}) { // <-- (4) - return nodes.length ? (cursor != null ? cursor : 0) + nodes.length : null; - }, - sort(ctx, query, {cursor, sort}) { // <-- (5) - if (cursor) { - query = query.skip(cursor); - } - - return query.sort({ - 'action_counts.like': sort === 'DESC' ? -1 : 1, - created_at: sort === 'DESC' ? -1 : 1, - }); - }, - }, - }, - }), -} -``` - -This has a bunch of special features: - -1. `Comments` is the name of the type being sorted, this is pluralized and - capitalized. -2. `likes` is the `sortBy` field in lowercase. -3. `startCursor` will retrieve the start cursor based on the current set of - nodes and the current cursor. -4. `endCursor` will retrieve the end cursor based on the current set of nodes - and the current cursor. -5. `sort` will mutate the `query` to apply the sort operations. - -All the `startCursor`, `endCursor`, and `sort` functions must be provided in -order for the sorting to apply properly. - -#### Field: `loaders` - -```js -(context) => ({ - People: { - load: () => db.people.find({user: context.user}) - } -}) -``` - -Loaders should be provided as a function which returns a map which is used in -the resolvers function. These must return a promise or a value. - -#### Field: `mutators` - -```js -(context) => ({ - People: { - create: (name) => { - return db.people.insert({user: context.user, name}); - } - } -}) -``` - -Mutators should be provided as a function which returns a map which is used in -the resolvers function. These must return a promise or a value. - -#### Field: `resolvers` - -```js -{ - Person: { - name(obj, args, context) { - return obj.name; - }, - colour(obj, args, context) { - // Bill likes the colour red, everyone else likes blue. - return obj.name === 'bill' ? 'RED' : 'BLUE'; - } - }, - RootQuery: { - people(obj, args, {loaders: {People}}) { - return People.load(); - } - }, - RootMutation: { - createPerson(obj, {name}, {mutators: {People}}) { - return People.create(name); - } - } -} -``` - -Should return a resolver map as described in the -[Apollo Docs](http://dev.apollodata.com/tools/graphql-tools/resolvers#Resolver-map). - -This will merge with the existing resolvers in core and from previous plugins. - -#### Field: `hooks` - -```js -{ - RootMutation: { - createPerson: { - post: async (obj, args, {plugins: {Slack}}, info, person) { - if (!person) { - return person; - } - - await Slack.notify(`A new person just was created with name ${person.name}`); - - return person; - } - } - } -} -``` - -Hooks here are pretty special, for each resolver field, you can specify a -pre/post hook that will execute pre and post field resolution. - -If your post function accepts four parameters, then it can modify the field -result. It is *required* that the function resolves a promise (or returns) with -the modified value or simply the original if you didn't modify it. - -#### Field: `setupFunctions` - -```js -setupFunctions: { - leader: (options, args) => ({ - leader: { - filter: (person) => person.place === 1 - }, - }), -} -``` - -Setup functions allow you to create filters that control which pubsub.publish() events -send data to the client. If the type in question contains args, clients may subscribe using those arguments to further filter their subscription. - -For more information, see the [Apollo Docs](https://github.com/apollographql/graphql-subscriptions). - -#### Field: `tokenUserNotFound` - -```js -tokenUserNotFound: async ({jwt, token}) => { - let profile = await someExternalService(token); - if (!profile) { - return null; - } - - let user = await UserModel.findOneAndUpdate({ - id: profile.id - }, { - id: profile.id, - username: profile.username, - lowercaseUsername: profile.username.toLowerCase(), - roles: [], - profiles: [] - }, { - setDefaultsOnInsert: true, - new: true, - upsert: true - }); - - return user; -} -``` - -The `tokenUserNotFound` hook allows auth integrations to hook into the event -when a valid token is provided but a user can't be found in the database that -matches the provided id. - -The function is async, and should return the user object that was created in the -database, or null if the user wasn't found. The `jwt` parameter of the object -is the unpacked token, while `token` is the original jwt token string. - -#### Field: `tags` - -The tags hook allows a plugin to define tags that are code controlled (added -or enabled by code). Below is an example pulled from the core off topic plugin -on how to create a hook for the `OFF_TOPIC` name: - -```js -[ - { - name: 'OFF_TOPIC', - permissions: { - public: true, - self: true, - roles: [] - }, - models: ['COMMENTS'], - created_at: new Date() - } -] -``` - -You can refer to `models/schema/tag.js` for the available schema to match when -creating models to enable/disable specific features. - -### Routes - -#### Field: `router` - -```js -(router) => { - router.get('/api/v1/people', (req, res) => { - res.json({people: [{name: 'Bob'}]}); - }); -} -``` - -The Router hook allows you to create a function that accepts the base express -router where you can mount any amount of middleware/routes to do any form of -action needed by external applications. - -### Authorization middleware - -The following example creates the requisite callback route and passport -strategy needed to enable Facebook Authorization: - -```js -const authorization = require('middleware/authorization'); - -module.exports = { - router(router) { - router.get('/api/v1/people', authorization.needed('ADMIN'), (req, res) => { - res.json({people: [{name: 'SECRET PEOPLE'}]}); - }); - } -} -``` - -#### Field: `passport` - -```js -const FacebookStrategy = require('passport-facebook').Strategy; -const UsersService = require('services/users'); -const {ValidateUserLogin, HandleAuthPopupCallback} = require('services/passport'); - -module.exports = { - passport(passport) { - passport.use(new FacebookStrategy({ - clientID: process.env.TALK_FACEBOOK_APP_ID, - clientSecret: process.env.TALK_FACEBOOK_APP_SECRET, - callbackURL: `${process.env.TALK_ROOT_URL}/api/v1/auth/facebook/callback`, - passReqToCallback: true, - profileFields: ['id', 'displayName', 'picture.type(large)'] - }, async (req, accessToken, refreshToken, profile, done) => { - - let user; - try { - user = await UsersService.findOrCreateExternalUser(profile); - } catch (err) { - return done(err); - } - - return ValidateUserLogin(profile, user, done); - })); - }, - router(router) { - - // Note that we have to import the passport instance here, it is - // instantiated after all the strategies have been mounted. - const {passport} = require('services/passport'); - - /** - * Facebook auth endpoint, this will redirect the user immediately to facebook - * for authorization. - */ - router.get('/facebook', passport.authenticate('facebook', {display: 'popup', authType: 'rerequest', scope: ['public_profile']})); - - /** - * Facebook callback endpoint, this will send the user a html page designed to - * send back the user credentials upon successful login. - */ - router.get('/facebook/callback', (req, res, next) => { - - // Perform the facebook login flow and pass the data back through the opener. - passport.authenticate('facebook', HandleAuthPopupCallback(req, res, next))(req, res, next); - }); - } -}; -``` - -## Full Example - -Contents of `plugins.json`: - -```json -{ - "server": [ - "people" - ] -} -``` - -Located in `plugins/people/index.js`: - -```js -module.exports = { - typeDefs: ` - enum COLOUR { - RED - BLUE - } - - type Person { - name: String! - colour: COLOUR! - } - - type RootMutation { - createPerson(name: String!): Person - } - - type RootQuery { - people: [Person!] - } - - type Subscription { - leader: Person - } - `, - context: { - Slack: () => ({ - notify: (message) => { - // return a promise after we're done sending notifications. - } - }) - }, - loaders: ({user}) => ({ - People: { - load: () => db.people.find({user}) - } - }), - mutators: ({user}) => ({ - People: { - create: (name) => { - return db.people.insert({user, name}); - } - } - }), - resolvers: { - Person: { - name(obj, args, context) { - return obj.name; - }, - colour(obj, args, context) { - // Bill likes the colour red, everyone else likes blue. - return obj.name === 'bill' ? 'RED' : 'BLUE'; - } - }, - RootQuery: { - people(obj, args, {loaders: {People}}) { - return People.load(); - } - }, - RootMutation: { - createPerson(obj, {name}, {mutators: {People}}) { - return People.create(name); - } - } - }, - hooks: { - RootMutation: { - createPerson: { - post: async (obj, args, {plugins: {Slack}}, info, person) => { - if (!person) { - return person; - } - - await Slack.notify(`A new person just was created with name ${person.name}`); - - return person; - } - } - } - }, - setupFunctions: { - leader: (options, args) => ({ - leader: { - filter: (person) => person.place === 1 - } - } - } -}; - -``` - -## API - -You can access any API available inside the talk directory in a plugin by simply -importing the file relative to the talk project root. An example would be if you -wanted to import the `MetadataService`, you would simply write: - -```javascript -const MetadataService = require('services/metadata'); -``` diff --git a/docs/_docs/04-05-plugins-experimental.md b/docs/_docs/04-05-plugins-experimental.md deleted file mode 100644 index 073094008..000000000 --- a/docs/_docs/04-05-plugins-experimental.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -title: Experimental Plugin API -permalink: /docs/plugins/experimental/ ---- - -Talk plugins are, in essence, small programs that hook into the core application in a variety of ways. Ultimately, this code can do anything that javascript is capable of. In addition, plugins can import any core code to hook into talk at any level. - -If you want to write plugins that integrate with core code beyond the api described -in the client api or server api section, please keep the following things in mind: - -* core code may change and break your plugin -* you may introduce inefficiencies with your plugin that could hurt performance/ -crash Talk -* you may cause bugs in other areas of Talk - -If you'd like to build a supported plugin but don't have the hooks you need, -please file an issue on this repo and we can discuss deepening the supported -plugin api! - -With that said, if you are still undeterred, here are some of the prime -experimental integration points: - -## Reducers and Actions : Redux - -Talk is powered by Redux and our plugins can too! Our plugins can have their own reducers and actions. - -```js -import MyButton from './MyButton'; -import reducer from './reducer'; - -export default { - slots: { - commentDetail: [MyButton], - }, - reducer -}; -``` - -## Import Actions from Talk -We can easily trigger `Talk` actions in our plugin Components. - -```js -import React, {Component} from 'react'; -import {connect} from 'react-redux'; -import {bindActionCreators} from 'redux'; -import {addTag, removeTag} from 'talk-plugin-commentbox/actions'; - -class MyButton extends Component { - render() { - return ; - } -} - -const mapStateToProps = ({commentBox}) => ({commentBox}); - -const mapDispatchToProps = dispatch => - bindActionCreators({addTag, removeTag}, dispatch); - -export default connect(mapStateToProps, mapDispatchToProps)(OffTopicCheckbox); -``` diff --git a/docs/_docs/05-01-development-tools.md b/docs/_docs/05-01-development-tools.md deleted file mode 100644 index e38775589..000000000 --- a/docs/_docs/05-01-development-tools.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: Development Tooling -permalink: /docs/development/tools/ ---- - -## Debugging -How we debug errors at Coral - -### React Debugging -For debugging React - -#### React Developer Tools -Another amazing tool for debugging React Applications. You can see where the props are, and much more. - -[React Developer Tools Extension](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en) - - -### Redux Debugging -For debugging Redux - -#### Redux Devtool Extension -Redux Devtool is an amazing debug tool. You can easily see what' happening with the state, the payloads, and more. - -[Redux Devtool Chrome Extension](https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd?hl=en) - -[Redux Devtool GitHub Repo](https://github.com/zalmoxisus/redux-devtools-extension) - -### GraphQL - -Talk ships with GraphiQL, a live data layer IDE. We strongly recommend using GraphiQL early and often as you work with all things queries, mutations and subscriptions! - -* [Install Talk]({{ "/docs/install/source" | absolute_url }}). -* Open http://localhost:3000/api/v1/graph/iql in your browser. (Note, your server an port may differ.) diff --git a/docs/_docs/05-04-rest-api.md b/docs/_docs/05-04-rest-api.md deleted file mode 100644 index dac80ae45..000000000 --- a/docs/_docs/05-04-rest-api.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: REST API -permalink: /docs/development/rest/ ---- - -Talk provides REST API documentation at [swagger.yaml]({{ "swagger.yaml" | absolute_url }}). \ No newline at end of file diff --git a/docs/_docs/installation-from-docker.md b/docs/_docs/installation-from-docker.md new file mode 100644 index 000000000..0126c0901 --- /dev/null +++ b/docs/_docs/installation-from-docker.md @@ -0,0 +1,122 @@ +--- +title: Installation from Docker +permalink: /installation-from-docker/ +--- + +{% include badges.html %} + +[Docker](https://www.docker.com/community-edition#/download){:target="_blank"} {{ site.versions.docker }} and +[Docker Compose](https://docs.docker.com/compose/install/){:target="_blank"} {{ site.versions.docker_compose }} are required +to perform installation via Docker. This is the recommended way to deploy the +application when used in production. + +Available as [coralproject/talk](https://hub.docker.com/r/coralproject/talk/){:target="_blank"} on +Docker Hub. [(latest/Dockerfile)](https://github.com/coralproject/talk/blob/master/Dockerfile){:target="_blank"} + +Images are tagged using the following notation: + +- `x` (where `x` is the major version number): any minor or patch updates will + be included in this. If you're ok getting new features occasionally and all + the bug fixes, this is the tag for you. Any changes to this image tag will not + require a database migration. +- `x.y` (where `y` is the minor version number): any patch updates will be + included with this tag. If you like getting fixes and having features change + only when you want, this is the tag for you. **(recommended)** +- `x.y.z` (where `z` is the patch version): this tag never gets updated, and + essentially freezes your version, this should only be used when you are either + extending Talk or are sure of a specific version you want to freeze. + +We provide tags with `*-onbuild` +[(onbuild/Dockerfile)](https://github.com/coralproject/talk/blob/master/Dockerfile.onbuild){:target="_blank"} +that can be used for easy plugin integration and acts as a customization +endpoint. To use this image tag, refer to the +[onbuild](#onbuild) section. + +## Installing + +To use Talk without major customization you can run the application using our +provided docker image. The following is a `docker-compose.yml` file that can +be used to setup Talk: + +```yml +{% include files/docker-compose.yml %} +``` + +This is the bare minimum needed to start Talk, for more configuration +variables, check out the [Configuration]({{ "/configuration/" | relative_url }}) section. +{: .code-aside} + +And you can then start it with: + +```bash +docker-compose up -d +``` + +This process will take a minute or two, it has to download docker images for the +required databases and Talk as well as setup the environments. + +Now that you've started the services started using compose, you should see +output that resembles the following: + +``` +Creating mongo_1 ... +Creating redis_1 ... +Creating mongo_1 ... done +Creating redis_1 ... done +Creating talk_1 ... +Creating talk_1 ... done +``` +{: .no-copy } + +And when you run `docker-compose ps`, you should see something like: + +``` + Name Command State Ports +------------------------------------------------------------------------------- +mongo_1 docker-entrypoint.sh mongod Up 27017/tcp +redis_1 docker-entrypoint.sh redis ... Up 6379/tcp +talk_1 yarn start Up 0.0.0.0:3000->3000/tcp +``` +{: .no-copy } + +At this stage, you should refer to the [configuration]({{ "/configuration/" | relative_url }}) for +configuration variables that are specific to your installation. + +## Onbuild + +We provide `*-onbuild` images to assist and automate the customization of our +base installation with additional custom plugins. Images can be created with the +most basic of `Dockerfile`'s: + +```docker +FROM coralproject/talk:latest-onbuild +``` + +And running the following to build the docker image: + +```bash +docker build -t my-awesome-talk-image . +``` + +Don't forget to replace `my-awesome-talk-image` with your own image name. +{: .code-aside} + +This accomplishes a lot: + +1. Copies all the files alongside the `Dockerfile` into the application + directory in the Docker image. +2. Installs any new dependencies that were required by any new plugins. +3. Builds the new static bundles so that they are ready to serve when the image + is running. + +This means that you can create a repository for your organization that simply +includes the above `Dockerfile`, a directory of `plugins`, and a `plugins.json` +file which specifies the activated plugins, and you can deploy Talk easily to +your containerized infrastructure. The versioning of our Docker tags as well +lets you do something like: + +```docker +FROM coralproject/talk:3.5-onbuild +``` + +Which would pin your image to `3.5` release's. \ No newline at end of file diff --git a/docs/_docs/installation-from-source.md b/docs/_docs/installation-from-source.md new file mode 100644 index 000000000..646a100a9 --- /dev/null +++ b/docs/_docs/installation-from-source.md @@ -0,0 +1,80 @@ +--- +title: Installation from Source +permalink: /installation-from-source/ +--- + +{% include badges.html %} + +To install Talk from Source, ensure that you have Node version +{{ site.versions.node }}. Installing via source is the recommended method when +developing as it give you the best tooling. We release versions using semantic +versioning, and do so to our +[Github Releases](https://github.com/coralproject/talk/releases){:target="_blank"} +page. There you can download archives of older versions or the latest release. +The examples following will download the latest code on our master branch. + +## Installing + +First we will download and extract the latest codebase of Talk: + +```bash +curl -sLo talk.tar.gz https://github.com/coralproject/talk/archive/master.tar.gz +mkdir -p talk +tar xzf talk.tar.gz -C talk --strip-components 1 +cd talk +``` + +From here we need to fetch the dependencies and build the static assets using +Yarn: + +```bash +yarn +yarn build +``` + +You can either setup the required databases by visiting the docs for [MongoDB](https://docs.mongodb.com/manual/installation/){:target="_blank"} and +[Redis](https://redis.io/topics/quickstart){:target="_blank"}, or using the following commands which will leverage Docker: + +```bash +docker run -p 127.0.0.1:6379:6379 -d redis +docker run -p 127.0.0.1:27017:27017 -d mongo +``` + +Didn't work? Sometimes you may already have a container running on these ports, +run `docker ps` to see what other containers you have running and running +`docker stop ` on those containers to stop them. +{: .code-aside} + +_This documentation assumes that you will be running MongoDB on +`127.0.0.1:27017` and Redis on `127.0.0.1:6379`. The above Docker commands bind +MongoDB and Redis on these interfaces for you._ + +We should then specify the configuration variables that can be used to run the +application locally in a file named `.env`. This will be read by the application +when running in development mode: + +```bash +NODE_ENV=development +TALK_MONGO_URL=mongodb://127.0.0.1:27017/talk +TALK_REDIS_URL=redis://127.0.0.1:6379 +TALK_ROOT_URL=http://127.0.0.1:3000 +TALK_PORT=3000 +TALK_JWT_SECRET=password +TALK_FACEBOOK_APP_ID=A-Facebook-App-ID +TALK_FACEBOOK_APP_SECRET=A-Facebook-App-Secret +``` + +This is the bare minimum needed to start Talk, for more configuration +variables, check out the [Configuration]({{ "/configuration/" | relative_url }}) +section. Facebook login above will definitely not work unless you change those +values as well. +{: .code-aside} + +You can now start the application by running: + +```bash +yarn dev-start +``` + +At this stage, you should refer to the [configuration]({{ "/configuration/" | relative_url }}) for +configuration variables that are specific to your installation. \ No newline at end of file diff --git a/docs/_docs/installation-talk-quickstart.md b/docs/_docs/installation-talk-quickstart.md new file mode 100644 index 000000000..c5e7a20ee --- /dev/null +++ b/docs/_docs/installation-talk-quickstart.md @@ -0,0 +1,185 @@ +--- +title: Talk Quickstart +permalink: / +--- + +{% include badges.html %} + +Online comments are broken. Our open-source Talk tool rethinks how moderation, +comment display, and conversation function, creating the opportunity for safer, +smarter discussions around your work. Read more about our product features and +goals [here](https://coralproject.net/products/talk.html){:target="_blank"}. The +documentation available here is pertaining to the technical details for +installing, configuring, and deploying Talk. + +Talk is a [Node](https://nodejs.org/){:target="_blank"} application with +dependencies managed by +[Yarn](https://yarnpkg.com/en/docs/install){:target="_blank"} that connects to +[MongoDB](https://docs.mongodb.com/manual/installation/){:target="_blank"} and +[Redis](https://redis.io/topics/quickstart){:target="_blank"} databases in order +to persist data. The following versions are supported: + +- Node {{ site.versions.node }} +- Yarn {{ site.versions.yarn }} +- MongoDB {{ site.versions.mongodb }} +- Redis {{ site.versions.redis }} + +An optional dependency for Talk is +[Docker](https://www.docker.com/community-edition#/download){:target="_blank"}. +It is used during [development](#development) to setup the database and can be +used to [install via Docker](#installation-from-docker). We have tested Talk +and this documentation with versions {{ site.versions.docker }}. + +Another optional dependency for Talk is +[Docker Compose](https://docs.docker.com/compose/install/){:target="_blank"}. It +can be used to setup your environment easily for testing. We have tested Talk +and this documentation with versions {{ site.versions.docker_compose }}. + +## Installation + +### Installation from Docker + +To use Talk without major customization you can run the application using our +provided docker image. The following is a `docker-compose.yml` file that can +be used to setup Talk: + +```yml +{% include files/docker-compose.yml %} +``` + +This is the bare minimum needed to run the demo, for more configuration +variables, check out the [Configuration]({{ "/configuration/" | relative_url }}) section. +{: .code-aside} + +And you can then start it with: + +```bash +docker-compose up -d +``` + +This process will take a minute or two, it has to download docker images for the +required databases and Talk as well as setup the environments. + +Now that you've started the services started using compose, you should see +output that resembles the following: + +``` +Creating mongo_1 ... +Creating redis_1 ... +Creating mongo_1 ... done +Creating redis_1 ... done +Creating talk_1 ... +Creating talk_1 ... done +``` +{: .no-copy } + +And when you run `docker-compose ps`, you should see something like: + +``` + Name Command State Ports +------------------------------------------------------------------------------- +mongo_1 docker-entrypoint.sh mongod Up 27017/tcp +redis_1 docker-entrypoint.sh redis ... Up 6379/tcp +talk_1 yarn start Up 0.0.0.0:3000->3000/tcp +``` +{: .no-copy } + +Continue onto the [Running](#running) section for details on how to complete the +installation and get started using Talk. + +### Installation from Source + +To install Talk from Source, ensure that you have the version of Node as +specified above. First we will download and extract the latest codebase of Talk: + +```bash +curl -sLo talk.tar.gz https://github.com/coralproject/talk/archive/master.tar.gz +mkdir -p talk +tar xzf talk.tar.gz -C talk --strip-components 1 +cd talk +``` + +From here we need to fetch the dependencies and build the static assets using +Yarn: + +```bash +yarn +yarn build +``` + +You can either setup the required databases by visiting the docs for [MongoDB](https://docs.mongodb.com/manual/installation/){:target="_blank"} and +[Redis](https://redis.io/topics/quickstart){:target="_blank"}, or using the following commands which will leverage Docker: + +```bash +docker run -p 127.0.0.1:6379:6379 -d redis +docker run -p 127.0.0.1:27017:27017 -d mongo +``` + +Didn't work? Sometimes you may already have a container running on these ports, +run `docker ps` to see what other containers you have running and running +`docker stop ` on those containers to stop them. +{: .code-aside} + +_This documentation assumes that you will be running MongoDB on +`127.0.0.1:27017` and Redis on `127.0.0.1:6379`. The above Docker commands bind +MongoDB and Redis on these interfaces for you._ + +We should then specify the configuration variables that can be used to run the +application locally in a file named `.env`. This will be read by the application +when running in development mode: + +```bash +NODE_ENV=development +TALK_MONGO_URL=mongodb://127.0.0.1:27017/talk +TALK_REDIS_URL=redis://127.0.0.1:6379 +TALK_ROOT_URL=http://127.0.0.1:3000 +TALK_PORT=3000 +TALK_JWT_SECRET=password +TALK_FACEBOOK_APP_ID=A-Facebook-App-ID +TALK_FACEBOOK_APP_SECRET=A-Facebook-App-Secret +``` + +This is only the bare minimum needed to run the demo, for more configuration +variables, check out the [Configuration]({{ "/configuration/" | relative_url }}) section. Facebook login above +will definitely not work unless you change those values as well. +{: .code-aside} + +You can now start the application by running: + +```bash +yarn dev-start +``` + +Continue onto the [Running](#running) section for details on how to complete the +installation and get started using Talk. + +## Running + +You can now navigate to +[http://127.0.0.1:3000/admin/install](http://127.0.0.1:3000/admin/install){:target="_blank"} +and go through the admin installation. There you will be prompted to create your +first admin account, and specify the domain whitelist for domains that are +allowed to have the comment box on. + +_During development, ensure you whitelist 127.0.0.1:3000 otherwise the +[http://127.0.0.1:3000/](http://127.0.0.1:3000/){:target="_blank"} page will not +load._ + +Once you've completed the installation, you can visit +[http://127.0.0.1:3000/](http://127.0.0.1:3000/){:target="_blank"} where you can +view our development area where we test out features in Talk where you can write +comments and see them in the admin interface where you can do moderation and +reconfigure the user experience. + +## Demo + +If you've followed the documentation above, you'll now have a running copy of +Talk. To demonstrate what your own self-hosted copy of Talk can do, below +you'll find a demo that can be used to test the copy that is running now on your +machine. + +{% include demo.html %} + +At this point you've successfully installed, configured, and ran your very own +instance of Talk! Continue through this documentation on this site to learn more +on how to configure, develop with, and contribute to Talk! \ No newline at end of file diff --git a/docs/_docs/04-01-plugins.md b/docs/_docs/plugins-overview.md similarity index 69% rename from docs/_docs/04-01-plugins.md rename to docs/_docs/plugins-overview.md index 3182f6e3a..5194bef04 100644 --- a/docs/_docs/04-01-plugins.md +++ b/docs/_docs/plugins-overview.md @@ -1,22 +1,30 @@ --- title: Plugins Overview -permalink: /docs/plugins/ +permalink: /plugins/ --- +Plugins are the integration point between the Talk core code and custom +functionality. We provide methods to inject behavior into the server side and +the client side application to affect different parts of the application +life cycle. + ## Recipes -Recipes are plugin templates provided by the Coral Core team. Developers can use these recipes to build their own plugins. You can find all the Talk recipes here: [https://github.com/coralproject/talk-recipes/](https://github.com/coralproject/talk-recipes/). +Recipes are plugin templates provided by the Coral Core team. Developers can use +these recipes to build their own plugins. You can find all the Talk recipes +here: [github.com/coralproject/talk-recipes](https://github.com/coralproject/talk-recipes/){:target="_blank"}. ## Plugin Registration -In order for a plugin to be active in a Talk install, it must be _registered_. The parsing order for the plugin registration is as follows: +In order for a plugin to be active in a Talk install, it must be _registered_. +The parsing order for the plugin registration is as follows: - `TALK_PLUGINS_JSON` environment variable - `plugins.json` file - `plugins.default.json` file If you need to "disable all plugins", you can simply provide `{}` as the -contents of `process.env.TALK_PLUGINS_JSON` or the `plugins.json`. +contents of `TALK_PLUGINS_JSON` or the `plugins.json`. The format for this is thus: @@ -53,11 +61,12 @@ External plugins can be resolved by running: This achieves two things: 1. It will traverse into local plugin folders and install their dependencies. - _Note that if the plugin is already installed and available in the node_modules folder, it will not be - fetched again unless there is a version mismatch._ This will result in the - project `package.json` and `yarn.lock` files to be modified, this is normal as - this ensures that repeated deployments (with the same config) will have the - same config, these changes should not be committed to source control. + _Note that if the plugin is already installed and available in the + node_modules folder, it will not be fetched again unless there is a version + mismatch._ This will result in the project `package.json` and `yarn.lock` + files to be modified, this is normal as this ensures that repeated deployments + (with the same config) will have the same config, these changes should not be + committed to source control. 2. It will seek out dependencies that are listed in the object notation and try to install them from npm. @@ -79,7 +88,7 @@ local plugins into the `plugins/` directory. After including the config, you need to reconcile the plugins and build the static assets: ```bash -# get plugin dependancies and remote plugins +# get plugin dependencies and remote plugins ./bin/cli plugins reconcile # build static assets (including enabled client side plugins) @@ -104,3 +113,7 @@ other local plugins that should be included. Onbuild triggers will execute when the image is building with your custom configuration and will ensure that the image is ready to use by building all assets inside the image as well. + +For more information on the onbuild image, refer to the +[Installation from Docker]({{ "/installation-from-docker/" | relative_url }}) +documentation. \ No newline at end of file diff --git a/docs/_docs/running-advanced-configuration.md b/docs/_docs/running-advanced-configuration.md new file mode 100644 index 000000000..5512f60cb --- /dev/null +++ b/docs/_docs/running-advanced-configuration.md @@ -0,0 +1,442 @@ +--- +title: Advanced Configuration +permalink: /advanced-configuration/ +class: configuration +--- + +Talk requires configuration in order to customize the installation. The default +behavior is to load it's configuration from the environment, following the +[12 Factor App Manifesto](https://12factor.net/){:target="_blank"}. +In development, you can specify configuration in a file named `.env` and it will +be loaded into the environment when you run `yarn dev-start`. + +The following variables have defaults, and are _optional_ to start your +instance of Talk: + +{% include toc.html %} + +If this is your first time configuring Talk, ensure you've also added the +[Required Configuration]({{ "/configuration/" | relative_url }}) as well, +otherwise the application will fail to start. + +## TALK_CACHE_EXPIRY_COMMENT_COUNT + +Configure the duration for which comment counts are cached for, parsed by +[ms](https://www.npmjs.com/package/ms){:target="_blank"}. (Default `1hr`) + +## TALK_DEFAULT_STREAM_TAB + +Specify the default stream tab in the admin. (Default `all`) + +## TALK_DISABLE_AUTOFLAG_SUSPECT_WORDS + +When `TRUE`, disables flagging of comments that match the suspect word filter. (Default `FALSE`) + +## TALK_DISABLE_EMBED_POLYFILL + +When set to `TRUE`, the build process will not include the +[babel-polyfill](https://babeljs.io/docs/usage/polyfill/){:target="_blank"} +in the embed.js target that is loaded on the page that loads the embed. (Default +`FALSE`) + +## TALK_DISABLE_STATIC_SERVER + +When `TRUE`, it will not mount the static asset serving routes on the router. +This is used primarily in conjunction with [TALK_STATIC_URI](#talk_static_uri){: .param} +when the static assets are being hosted on an external domain. (Default `FALSE`) + +## TALK_HELMET_CONFIGURATION + +A JSON string representing the configuration passed to the +[helmet](https://github.com/helmetjs/helmet){:target="_blank"} middleware. It +can be used to disable features like [HSTS](https://helmetjs.github.io/docs/hsts/){:target="_blank"} +and others by simply providing the configuration as detailed on the +[helmet docs](https://helmetjs.github.io/docs/){:target="_blank"}. (Default `{}`) + +For sites that do not have SSL enabled on all their pages across their domain, +it is critical that you specify the following to disable the +[HSTS](https://helmetjs.github.io/docs/hsts/){:target="_blank"} headers from +being sent: + +```plain +TALK_HELMET_CONFIGURATION={"hsts": false} +``` + +To disable these headers from being sent. + +## TALK_INSTALL_LOCK + +When `TRUE`, disables the dynamic setup endpoint `/admin/install` from even +loading. This prevents hits to the database with enabled. This should always be +set to `TRUE` after you've deployed Talk. (Default `FALSE`) + +## TALK_JWT_ALG + +The algorithm used to sign/verify JWT’s used for session management. Read up +about alternative algorithms on the +[jsonwebtoken](https://www.npmjs.com/package/jsonwebtoken#algorithms-supported){:target="_blank"} +package. (Default `HS256`) + +### Shared Secret +{:.no_toc} + +You would use a shared secret when you have no need to share the tokens with +other applications in your organization. + +Supported signing algorithms: + +- HS256 +- HS384 +- HS512 + +These must be provided in the form: + +```json +{ + "secret": "" +} +``` +{: .no-copy} + +### Asymmetric Secret +{:.no_toc} + +You would use a asymmetric secret when you want to share the token in your +organization, and would like to pass an existing auth token to Talk in order to +authenticate your users. + +Supported signing algorithms: + +- RS256 +- RS384 +- RS512 +- ES256 +- ES384 +- ES512 + +These must be provided in the form: + +```json +{ + "public": "", + "private": "" +} +``` +{: .no-copy} + +Note that when using the asymmetric keys as discussed above, the certificates +must have their newlines replaced with `\\n`, this is to ensure that the +newlines are preserved after JSON decoding. Not doing so will result in parsing +errors. + +To assist with this process, we have developed a tool that can generate new +certificates that match our required format: [coralcert](https://github.com/coralproject/coralcert){:target="_blank"}. +This tool can generate RSA and ECDSA certificates, check it's [README](https://github.com/coralproject/coralcert){:target="_blank"} +for more details. + +## TALK_JWT_AUDIENCE + +The audience [aud](https://tools.ietf.org/html/rfc7519#section-4.1.3){:target="_blank"} +claim for login JWT tokens. (Default `talk`) + +## TALK_JWT_CLEAR_COOKIE_LOGOUT + +When `FALSE`, Talk will not clear the cookie with name +[TALK_JWT_SIGNING_COOKIE_NAME](#talk_jwt_signing_cookie_name){: .param} when logging out +but will still blacklist the token. (Default `TRUE`) + +## TALK_JWT_COOKIE_NAME + +The default cookie name to check for a valid JWT token to use for verifying a +user. (Default `authorization`) + +## TALK_JWT_COOKIE_NAMES + +The different cookie names to check for a JWT token in, separated by a `,`. By +default, we always use the value of [TALK_JWT_COOKIE_NAME](#talk_jwt_cookie_name){: .param} +and [TALK_JWT_SIGNING_COOKIE_NAME](#talk_jwt_signing_cookie_name){: .param} for this +value. Any additional cookie names specified here will be appended to the list +of cookie names to inspect. + +For example, the value of: + +```plain +TALK_JWT_COOKIE_NAME=talk +TALK_JWT_SIGNING_COOKIE_NAME=talk +TALK_JWT_COOKIE_NAMES=coralproject.talk,coralproject.auth +``` + +Would mean we would check the following cookies (in order) for a valid token: + +1. `talk` +2. `coralproject.talk` +3. `coralproject.auth` + +## TALK_JWT_DISABLE_AUDIENCE + +When `TRUE`, Talk will not verify or sign JWT’s with an audience +[aud](https://tools.ietf.org/html/rfc7519#section-4.1.3){:target="_blank"} +claim, even if [TALK_JWT_AUDIENCE](#talk_jwt_audience){: .param} is set. (Default `FALSE`) + +## TALK_JWT_DISABLE_ISSUER + +When `TRUE`, Talk will not verify or sign JWT’s with an issuer +[iss](https://tools.ietf.org/html/rfc7519#section-4.1.1){:target="_blank"} +claim, even if [TALK_JWT_ISSUER](#talk_jwt_issuer){: .param} is set. (Default `FALSE`) + +## TALK_JWT_EXPIRY + +The expiry duration [exp](https://tools.ietf.org/html/rfc7519#section-4.1.4){:target="_blank"} +for the tokens issued for logged in sessions, parsed by +[ms](https://www.npmjs.com/package/ms){:target="_blank"}. (Default `1 day`) + +If the user logs out, then an entry is created in the token blacklist of it's +[jti](https://tools.ietf.org/html/rfc7519#section-4.1.7){:target="_blank"} for +set to be automatically removed at it's expiry time. It is important for this +reason to create reasonable expiry lengths as to minimize the storage overhead. + +## TALK_JWT_ISSUER + +The issuer [iss](https://tools.ietf.org/html/rfc7519#section-4.1.1){:target="_blank"} +claim for login JWT tokens. (Defaults to value of [TALK_ROOT_URL]({{ "/configuration/#talk_root_url" | relative_url }}){: .param}) + +## TALK_JWT_SECRET + +Used to specify the application signing secret. You can specify this using a +simple string, we recommend using a password generator and pasting it's output. +An example for `TALK_JWT_SECRET` could be: + +```plain +TALK_JWT_SECRET=jX9y8G2ApcVLwyL{$6s3 +``` +{: .no-copy} + +You can also express this secret in the JSON syntax: + +```plain +TALK_JWT_SECRET={"secret": "jX9y8G2ApcVLwyL{$6s3"} +``` + +Refer to the documentation for [TALK_JWT_ALG](#talk_jwt_alg){: .param} for other signing +methods and other forms of the `TALK_JWT_SECRET`. If you are interested in using +multiple keys, then refer to [TALK_JWT_SECRETS](#talk_jwt_secrets){: .param}. + +## TALK_JWT_SECRETS + +Used when specifying multiple secrets used for key rotations. This is a JSON +encoded array, where each element matches the JWT Secret pattern. When this is +used, you do not need to specify a [TALK_JWT_SECRET](#talk_jwt_secret){: .param} as this +will take precedence. **The first secret in `TALK_JWT_SECRETS` will be used for +signing, and must contain a private key if used with an asymmetric algorithm.** + +All secrets should specify a `kid` field which uniquely identifies a given key +and will sign all tokens with that `kid` for later identification. + +When the value of [TALK_JWT_ALG](#talk_jwt_alg){: .param} is a `HS*` value, then the value +of the `TALK_JWT_SECRETS` should take the form: + +```plain +TALK_JWT_SECRETS=[{"kid": "1", "secret": "my-super-secret"}, {"kid": "2", "secret": "my-other-super-secret"}] +``` +{: .no-copy} + +Note that the secret is stored in a JSON object, keyed by `secret`. This is only +needed when specifying in the multiple secrets for `TALK_JWT_SECRETS`, but may +be used to specify the single [TALK_JWT_SECRET](#talk_jwt_secret){: .param}. +{: .code-aside} + +When the value of [TALK_JWT_ALG](#talk_jwt_alg){: .param} is **not** a `HS*` value, then +the value of the `TALK_JWT_SECRETS` should take the form: + +```plain +TALK_JWT_SECRETS=[{"kid": "1", "private": "", "public": ""}, ...] +``` +{: .no-copy} + +Refer to the documentation on the [TALK_JWT_ALG](#talk_jwt_alg){: .param} for more +information on what to store in these parameters. +{: .code-aside} + +## TALK_JWT_SIGNING_COOKIE_NAME + +The default cookie name that is use to set a cookie containing a JWT that was +issued by Talk. (Defaults to value of [TALK_JWT_COOKIE_NAME](#talk_jwt_cookie_name){: .param}) + +## TALK_JWT_USER_ID_CLAIM + +Specify the claim using dot notation for where the user id should be stored/read +to/from. (Default `sub`) + +If for example, the JWT's claims looks something like this: + +```json +{ + "user": { + "id": "123123" + } +} +``` + +Then we would set `TALK_JWT_USER_ID_CLAIM` to: + +```plain +TALK_JWT_USER_ID_CLAIM=user.id +``` + +## TALK_KEEP_ALIVE + +The keepalive timeout that should be used to send keep alive messages through +the websocket to keep the socket alive, parsed by +[ms](https://www.npmjs.com/package/ms){:target="_blank"}. (Default `30s`) + +## TALK_RECAPTCHA_PUBLIC + +Client secret used for enabling reCAPTCHA powered logins. If +[TALK_RECAPTCHA_SECRET](#talk_recaptcha_secret){: .param} and +[TALK_RECAPTCHA_PUBLIC](#talk_recaptcha_public){: .param} are not provided it will instead +default to providing only a time based lockout. Refer to +[reCAPTCHA](https://www.google.com/recaptcha/intro/index.html) for information +on getting an account setup. + +## TALK_RECAPTCHA_SECRET + +Server secret used for enabling reCAPTCHA powered logins. If +[TALK_RECAPTCHA_SECRET](#talk_recaptcha_secret){: .param} and +[TALK_RECAPTCHA_PUBLIC](#talk_recaptcha_public){: .param} are not provided it will instead +default to providing only a time based lockout. Refer to +[reCAPTCHA](https://www.google.com/recaptcha/intro/index.html) for information +on getting an account setup. + +## TALK_REDIS_CLIENT_CONFIG + +Configuration overrides for the redis client configuration in a JSON encoded +string. Configuration is overridden as the second parameter to the redis client +constructor, and is merged with default configuration. Refer to the +[ioredis](https://github.com/luin/ioredis){:target="_blank"} docs on the +available options. (Default `{}`) + +## TALK_REDIS_CLUSTER_CONFIGURATION + +The JSON encoded form of the cluster nodes. Only required when +[TALK_REDIS_CLUSTER_MODE](#talk_redis_cluster_mode){: .param} is `CLUSTER`. See +[https://github.com/luin/ioredis#cluster](https://github.com/luin/ioredis#cluster){:target="_blank"} +for configuration details. (Default `[]`) + +## TALK_REDIS_CLUSTER_MODE + +The cluster mode of the redis client. Can be either `NONE` or `CLUSTER`. +(Default `NONE`) + +## TALK_REDIS_RECONNECTION_BACKOFF_FACTOR + +The time factor that will be multiplied against the current attempt count +between attempts to connect to redis, parsed by +[ms](https://www.npmjs.com/package/ms){:target="_blank"}. (Default `500 ms`) + +## TALK_REDIS_RECONNECTION_BACKOFF_MINIMUM_TIME + +The minimum time used to delay before attempting to reconnect to redis, parsed +by [ms](https://www.npmjs.com/package/ms){:target="_blank"}. (Default `1 sec`) + +## TALK_ROOT_URL_MOUNT_PATH + +When set to `TRUE`, the routes will be mounted onto the `` component +of the [TALK_ROOT_URL]({{ "/configuration/#talk_root_url" | relative_url }}){: .param}. +You would use this when your upstream proxy cannot strip the prefix from the +url. (Default `FALSE`) + +If for example, you had the following configuration: + +```plain +TALK_ROOT_URL=https://coralproject.net/talk/ +TALK_ROOT_URL_MOUNT_PATH=TRUE +``` + +Then all the routes for the API will be expecting to be hit on `/talk/`, such as +`/talk/api/v1/graph/ql` instead of `/api/v1/graph/ql`. Most modern webservers +can perform the path stripping when serving an upstream proxy, but some CDN's +cannot. You would use this option in the latter situation. + +## TALK_SMTP_EMAIL + +The email address to send emails from using the SMTP provider in the format: + +```plain +TALK_SMTP_EMAIL="The Coral Project" +``` + +Including the name and email address. + +## TALK_SMTP_HOST + +The domain for the SMTP provider that you are using. + +## TALK_SMTP_PASSWORD + +The password for the SMTP provider you are using. + +## TALK_SMTP_PORT + +The port for the SMTP provider that you are using. + +## TALK_SMTP_USERNAME + +The username of the SMTP provider you are using. + +## TALK_STATIC_URI + +Used to set the uri where the static assets should be served from. This is used +when you want to upload the static assets through your build process to a +service like Google Cloud Storage or Amazon S3 and you would then specify the +CDN/Storage url. (Defaults to value of +[TALK_ROOT_URL]({{ "/configuration/#talk_root_url" | relative_url }}){: .param}) + +## TALK_THREADING_LEVEL + +Specify the maximum depth of the comment thread. (Default `3`) + +**Note that a high value for `TALK_THREADING_LEVEL` will result in large +performance impacts.** + +## TALK_WEBSOCKET_LIVE_URI + +Used to override the location to connect to the websocket endpoint to +potentially another host. This should be used when you need to route websocket +requests out of your CDN in order to serve traffic more efficiently. + +If the value of [TALK_ROOT_URL]({{ "/configuration/#talk_root_url" | relative_url }}){: .param} +is a https url, then this defaults to `wss://${location.host}${MOUNT_PATH}api/v1/live`. +Otherwise, it defaults to `ws://${location.host}${MOUNT_PATH}api/v1/live`. + +Where `MOUNT_PATH` is either `/` if [TALK_ROOT_URL_MOUNT_PATH](#talk_root_url_mount_path){: .param} +is `FALSE`, or the path component of +[TALK_ROOT_URL]({{ "/configuration/#talk_root_url" | relative_url }}){: .param} if it's `TRUE`. + +**Warning: if used without managing the auth state manually, auth +cannot be persisted due to browser restrictions.** + +## TRUST_THRESHOLDS + +Configure the reliability thresholds for flagging and commenting. (Default +`comment:2,-1;flag:2,-1`) + +The form of the environment variable: + +```plain +TRUST_THRESHOLDS=comment:,;flag:, +``` + +The default value of: + +```plain +TRUST_THRESHOLDS=comment:2,-1;flag:2,-1 +``` + +Could be read as: + +- When a commenter has one comment rejected, their next comment must be + pre-moderated once in order to post freely again. If they instead get rejected + again, then they must have two of their comments approved in order to get + added back to the queue. +- At the moment of writing, behavior is not attached to the flagging + reliability, but it is recorded. \ No newline at end of file diff --git a/docs/_docs/running-required-configuration.md b/docs/_docs/running-required-configuration.md new file mode 100644 index 000000000..2f5d28049 --- /dev/null +++ b/docs/_docs/running-required-configuration.md @@ -0,0 +1,106 @@ +--- +title: Required Configuration +permalink: /configuration/ +class: configuration +--- + +Talk requires configuration in order to customize the installation. The default +behavior is to load it's configuration from the environment, following the +[12 Factor App Manifesto](https://12factor.net/){:target="_blank"}. +In development, you can specify configuration in a file named `.env` and it will +be loaded into the environment when you run `yarn dev-start`. + +The following variables do not have defaults, and are **required** to start your +instance of Talk: + +{% include toc.html %} + +If you've already configured your application with the required configuration, +you can further customize it's behavior by applying +[Advanced Configuration]({{ "/advanced-configuration/" | relative_url }}). + +## TALK_MONGO_URL + +The database connection string for the MongoDB database. This usually takes the +form of: + +```plain +TALK_MONGO_URL=mongodb://:@:/ +``` + +Refer to [connection string uri format](https://docs.mongodb.com/manual/reference/connection-string/){:target="_blank"} +for the detailed url scheme of the MongoDB url. + +## TALK_REDIS_URL + +The database connection string for the Redis database. This usually takes the +form of: + +```plain +TALK_REDIS_URL=redis://user:@:/ +``` + +If we for example, had Redis running on our local machine without a password, +where I want to use database #2, I could set the `TALK_REDIS_URL` to: + +```plain +TALK_REDIS_URL=redis://127.0.0.1:6379/2 +``` + +Refer to [uri scheme](http://www.iana.org/assignments/uri-schemes/prov/redis){:target="_blank"} +for the detailed url scheme of the Redis url. + +## TALK_ROOT_URL + +The root url of the installed application externally available in the format: + +```plain +TALK_ROOT_URL=://:/ +``` + +For example, if we installed our application onto the `talk.coralproject.net` +domain, where we used a proxy like [Caddy](https://caddyserver.com){:target="_blank"} +or [Nginx](https://nginx.org){:target="_blank"} to perform SSL termination, then +`TALK_ROOT_URL` would be: + +```plain +TALK_ROOT_URL=https://talk.coralproject.net/ +``` + +_Note that we omitted the `PORT`, as it was implied by setting the `SCHEME` to +`https`._ + +## TALK_JWT_SECRET + +Used to specify the application signing secret. You can specify this using a +simple string, we recommend using a password generator and pasting it's output. +An example for `TALK_JWT_SECRET` could be: + +```plain +TALK_JWT_SECRET=jX9y8G2ApcVLwyL{$6s3 +``` +{: .no-copy} + +Be default, we sign our tokens with HMAC using a SHA-256 hash algorithm. If you +want to change the signing algorithm, or use multiple signing/verifying keys, +refer to our [Advanced Configuration]({{ "/advanced-configuration/" | relative_url }}) documentation. + +## TALK_FACEBOOK_APP_ID + +The Facebook App ID for your Facebook Login enabled app. You can learn more +about getting a Facebook App ID at the +[Facebook Developers Portal](https://developers.facebook.com){:target="_blank"} +or by visiting the +[Creating an App ID](https://developers.facebook.com/docs/apps/register){:target="_blank"} +guide. This is only required while the `talk-plugin-facebook-auth` plugin is +enabled. + +## TALK_FACEBOOK_APP_SECRET + +The Facebook App Secret for your Facebook Login enabled app. You can learn more +about getting a Facebook App Secret at the +[Facebook Developers Portal](https://developers.facebook.com){:target="_blank"} +or by visiting the +[Creating an App ID](https://developers.facebook.com/docs/apps/register){:target="_blank"} +guide. This is only required while the `talk-plugin-facebook-auth` plugin is +enabled. \ No newline at end of file diff --git a/docs/_includes/analytics-providers/custom.html b/docs/_includes/analytics-providers/custom.html deleted file mode 100755 index c34b97ad9..000000000 --- a/docs/_includes/analytics-providers/custom.html +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/docs/_includes/analytics-providers/google-universal.html b/docs/_includes/analytics-providers/google-universal.html deleted file mode 100755 index 10d65b2ee..000000000 --- a/docs/_includes/analytics-providers/google-universal.html +++ /dev/null @@ -1,9 +0,0 @@ - diff --git a/docs/_includes/analytics-providers/google.html b/docs/_includes/analytics-providers/google.html deleted file mode 100755 index b591b9954..000000000 --- a/docs/_includes/analytics-providers/google.html +++ /dev/null @@ -1,11 +0,0 @@ - \ No newline at end of file diff --git a/docs/_includes/analytics.html b/docs/_includes/analytics.html deleted file mode 100755 index 64a3359aa..000000000 --- a/docs/_includes/analytics.html +++ /dev/null @@ -1,12 +0,0 @@ -{% if site.analytics.provider and page.analytics != false %} - -{% case site.analytics.provider %} -{% when "google" %} - {% include /analytics-providers/google.html %} -{% when "google-universal" %} - {% include /analytics-providers/google-universal.html %} -{% when "custom" %} - {% include /analytics-providers/custom.html %} -{% endcase %} - -{% endif %} \ No newline at end of file diff --git a/docs/_includes/archive-single.html b/docs/_includes/archive-single.html deleted file mode 100755 index 93755e38e..000000000 --- a/docs/_includes/archive-single.html +++ /dev/null @@ -1,38 +0,0 @@ -{% if post.header.teaser %} - {% capture teaser %}{{ post.header.teaser }}{% endcapture %} -{% else %} - {% assign teaser = site.teaser %} -{% endif %} - -{% if post.id %} - {% assign title = post.title | markdownify | remove: "

" | remove: "

" %} -{% else %} - {% assign title = post.title %} -{% endif %} - -
-
- {% if include.type == "grid" and teaser %} -
- -
- {% endif %} -

- {% if post.link %} - {{ title }} Permalink - {% else %} - {{ title }} - {% endif %} -

- {% if post.read_time %} -

{% include read-time.html %}

- {% endif %} - {% if post.excerpt %}

{{ post.excerpt | markdownify | strip_html | truncate: 160 }}

{% endif %} -
-
\ No newline at end of file diff --git a/docs/_includes/author-profile-custom-links.html b/docs/_includes/author-profile-custom-links.html deleted file mode 100755 index 3560e2588..000000000 --- a/docs/_includes/author-profile-custom-links.html +++ /dev/null @@ -1,7 +0,0 @@ - \ No newline at end of file diff --git a/docs/_includes/author-profile.html b/docs/_includes/author-profile.html deleted file mode 100755 index 2d1054312..000000000 --- a/docs/_includes/author-profile.html +++ /dev/null @@ -1,249 +0,0 @@ -{% if page.author and site.data.authors[page.author] %} - {% assign author = site.data.authors[page.author] %} -{% else %} - {% assign author = site.author %} -{% endif %} - -
- - {% if author.avatar %} -
- {% if author.avatar contains "://" %} - {{ author.name }} - {% else %} - {{ author.name }} - {% endif %} -
- {% endif %} - -
-

{{ author.name }}

- {% if author.bio %} -

- {{ author.bio }} -

- {% endif %} -
- -
- - -
-
diff --git a/docs/_includes/badges.html b/docs/_includes/badges.html new file mode 100644 index 000000000..2c2e12fd9 --- /dev/null +++ b/docs/_includes/badges.html @@ -0,0 +1,3 @@ +{% for item in site.data.badges.items %} + {{ item.title }} +{% endfor %} \ No newline at end of file diff --git a/docs/_includes/base_path b/docs/_includes/base_path deleted file mode 100755 index 36826c4f2..000000000 --- a/docs/_includes/base_path +++ /dev/null @@ -1,5 +0,0 @@ -{% if site.url %} - {% assign base_path = site.url | append: site.baseurl %} -{% else %} - {% assign base_path = site.github.url %} -{% endif %} \ No newline at end of file diff --git a/docs/_includes/breadcrumbs.html b/docs/_includes/breadcrumbs.html deleted file mode 100755 index 6eec214b9..000000000 --- a/docs/_includes/breadcrumbs.html +++ /dev/null @@ -1,39 +0,0 @@ -{% case site.category_archive.type %} - {% when "liquid" %} - {% assign path_type = "#" %} - {% when "jekyll-archives" %} - {% assign path_type = nil %} -{% endcase %} - -{% if page.collection != 'posts' %} - {% assign path_type = nil %} - {% assign crumb_path = '/' %} -{% else %} - {% assign crumb_path = site.category_archive.path %} -{% endif %} - - diff --git a/docs/_includes/browser-upgrade.html b/docs/_includes/browser-upgrade.html deleted file mode 100755 index e8d8b2625..000000000 --- a/docs/_includes/browser-upgrade.html +++ /dev/null @@ -1,3 +0,0 @@ - \ No newline at end of file diff --git a/docs/_includes/category-list.html b/docs/_includes/category-list.html deleted file mode 100755 index 039d5e2e7..000000000 --- a/docs/_includes/category-list.html +++ /dev/null @@ -1,26 +0,0 @@ -{% case site.category_archive.type %} - {% when "liquid" %} - {% assign path_type = "#" %} - {% when "jekyll-archives" %} - {% assign path_type = nil %} -{% endcase %} - -{% if site.category_archive.path %} - {% comment %} - - - {% endcomment %} - {% capture page_categories %}{% for category in page.categories %}{{ category | downcase }}#{{ category }}{% unless forloop.last %},{% endunless %}{% endfor %}{% endcapture %} - {% assign category_hashes = (page_categories | split: ',' | sort:0) %} - -

- {{ site.data.ui-text[site.locale].categories_label | default: "Categories:" }} - - {% for hash in category_hashes %} - {% assign keyValue = hash | split: '#' %} - {% capture category_word %}{{ keyValue[1] | strip_newlines }}{% endcapture %} - {% unless forloop.last %}, {% endunless %} - {% endfor %} - -

-{% endif %} \ No newline at end of file diff --git a/docs/_includes/comment.html b/docs/_includes/comment.html deleted file mode 100755 index 44c07d1a1..000000000 --- a/docs/_includes/comment.html +++ /dev/null @@ -1,22 +0,0 @@ - \ No newline at end of file diff --git a/docs/_includes/comments-providers/custom.html b/docs/_includes/comments-providers/custom.html deleted file mode 100755 index 90993691e..000000000 --- a/docs/_includes/comments-providers/custom.html +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/docs/_includes/comments-providers/discourse.html b/docs/_includes/comments-providers/discourse.html deleted file mode 100755 index aca62cc84..000000000 --- a/docs/_includes/comments-providers/discourse.html +++ /dev/null @@ -1,13 +0,0 @@ -{% if site.comments.discourse.server %} -{% capture canonical %}{% if site.permalink contains '.html' %}{{ page.url | absolute_url }}{% else %}{{ page.url | absolute_url | remove:'index.html' | strip_slash }}{% endif %}{% endcapture %} - - -{% endif %} diff --git a/docs/_includes/comments-providers/disqus.html b/docs/_includes/comments-providers/disqus.html deleted file mode 100755 index c6fc691de..000000000 --- a/docs/_includes/comments-providers/disqus.html +++ /dev/null @@ -1,22 +0,0 @@ -{% if site.comments.disqus.shortname %} - - -{% endif %} \ No newline at end of file diff --git a/docs/_includes/comments-providers/facebook.html b/docs/_includes/comments-providers/facebook.html deleted file mode 100755 index 009dc1c6c..000000000 --- a/docs/_includes/comments-providers/facebook.html +++ /dev/null @@ -1,8 +0,0 @@ -
- \ No newline at end of file diff --git a/docs/_includes/comments-providers/google-plus.html b/docs/_includes/comments-providers/google-plus.html deleted file mode 100755 index 0b4ff6b7e..000000000 --- a/docs/_includes/comments-providers/google-plus.html +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/docs/_includes/comments-providers/scripts.html b/docs/_includes/comments-providers/scripts.html deleted file mode 100755 index 1eb536f25..000000000 --- a/docs/_includes/comments-providers/scripts.html +++ /dev/null @@ -1,16 +0,0 @@ -{% if site.comments.provider and page.comments %} - {% case site.comments.provider %} - {% when "disqus" %} - {% include /comments-providers/disqus.html %} - {% when "discourse" %} - {% include /comments-providers/discourse.html %} - {% when "facebook" %} - {% include /comments-providers/facebook.html %} - {% when "google-plus" %} - {% include /comments-providers/google-plus.html %} - {% when "staticman" %} - {% include /comments-providers/staticman.html %} - {% when "custom" %} - {% include /comments-providers/custom.html %} - {% endcase %} -{% endif %} \ No newline at end of file diff --git a/docs/_includes/comments-providers/staticman.html b/docs/_includes/comments-providers/staticman.html deleted file mode 100755 index 471fa867c..000000000 --- a/docs/_includes/comments-providers/staticman.html +++ /dev/null @@ -1,42 +0,0 @@ -{% if site.repository and site.staticman.branch %} - -{% endif %} \ No newline at end of file diff --git a/docs/_includes/comments.html b/docs/_includes/comments.html deleted file mode 100755 index 6f57edc95..000000000 --- a/docs/_includes/comments.html +++ /dev/null @@ -1,95 +0,0 @@ -
- {% capture comments_label %}{{ site.data.ui-text[site.locale].comments_label | default: "Comments" }}{% endcapture %} - {% case site.comments.provider %} - {% when "discourse" %} -

{{ comments_label }}

-
- {% when "disqus" %} -

{{ comments_label }}

-
- {% when "facebook" %} -

{{ comments_label }}

-
- {% when "google-plus" %} -

{{ comments_label }}

-
Loading Google+ Comments ...
- - + + + + + + - diff --git a/docs/_includes/footer/custom.html b/docs/_includes/footer/custom.html deleted file mode 100755 index d512599d1..000000000 --- a/docs/_includes/footer/custom.html +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/docs/_includes/gallery b/docs/_includes/gallery deleted file mode 100755 index 5983239c4..000000000 --- a/docs/_includes/gallery +++ /dev/null @@ -1,47 +0,0 @@ -{% if include.id %} - {% assign gallery = page.[include.id] %} -{% else %} - {% assign gallery = page.gallery %} -{% endif %} - -{% if gallery.size == 2 %} - {% assign gallery_layout = 'half' %} -{% elsif gallery.size >= 3 %} - {% assign gallery_layout = 'third' %} -{% else %} - {% assign gallery_layout = '' %} -{% endif %} - - \ No newline at end of file diff --git a/docs/_includes/group-by-array b/docs/_includes/group-by-array deleted file mode 100755 index 251302c70..000000000 --- a/docs/_includes/group-by-array +++ /dev/null @@ -1,47 +0,0 @@ - - - -{% assign __empty_array = '' | split: ',' %} -{% assign group_names = __empty_array %} -{% assign group_items = __empty_array %} - - -{% assign __names = include.collection | map: include.field %} - - -{% assign __names = __names | join: ',' | join: ',' | split: ',' %} - - -{% assign __names = __names | sort %} -{% for name in __names | sort %} - - -{% unless name == previous %} - - -{% assign group_names = group_names | push: name %} -{% endunless %} - -{% assign previous = name %} -{% endfor %} - - - -{% for name in group_names %} - - -{% assign __item = __empty_array %} -{% for __element in include.collection %} -{% if __element[include.field] contains name %} -{% assign __item = __item | push: __element %} -{% endif %} -{% endfor %} - - -{% assign group_items = group_items | push: __item %} -{% endfor %} \ No newline at end of file diff --git a/docs/_includes/head.html b/docs/_includes/head.html old mode 100755 new mode 100644 index cb675e2cb..768f76aca --- a/docs/_includes/head.html +++ b/docs/_includes/head.html @@ -1,34 +1,10 @@ - - -{% include seo.html %} - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + {% seo %} + + + + + \ No newline at end of file diff --git a/docs/_includes/head/custom.html b/docs/_includes/head/custom.html deleted file mode 100755 index 017673132..000000000 --- a/docs/_includes/head/custom.html +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/docs/_includes/header.html b/docs/_includes/header.html new file mode 100644 index 000000000..5dc932b61 --- /dev/null +++ b/docs/_includes/header.html @@ -0,0 +1,12 @@ +
+ +
\ No newline at end of file diff --git a/docs/_includes/images/hamburger.svg b/docs/_includes/images/hamburger.svg new file mode 100644 index 000000000..42f894d1e --- /dev/null +++ b/docs/_includes/images/hamburger.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/docs/_includes/images/logo.svg b/docs/_includes/images/logo.svg new file mode 100644 index 000000000..5eda0c205 --- /dev/null +++ b/docs/_includes/images/logo.svg @@ -0,0 +1,41 @@ + \ No newline at end of file diff --git a/docs/_includes/images/moz-logo-bw-rgb.svg b/docs/_includes/images/moz-logo-bw-rgb.svg new file mode 100644 index 000000000..08f06e057 --- /dev/null +++ b/docs/_includes/images/moz-logo-bw-rgb.svg @@ -0,0 +1,22 @@ + + + + + + + + + diff --git a/docs/_includes/masthead.html b/docs/_includes/masthead.html deleted file mode 100755 index 5856b92de..000000000 --- a/docs/_includes/masthead.html +++ /dev/null @@ -1,21 +0,0 @@ -
-
-
- -
-
-
\ No newline at end of file diff --git a/docs/_includes/nav_list b/docs/_includes/nav_list deleted file mode 100755 index d264577a4..000000000 --- a/docs/_includes/nav_list +++ /dev/null @@ -1,47 +0,0 @@ -{% assign navigation = site.data.navigation[include.nav] %} - - \ No newline at end of file diff --git a/docs/_includes/page__hero.html b/docs/_includes/page__hero.html deleted file mode 100755 index 24488932a..000000000 --- a/docs/_includes/page__hero.html +++ /dev/null @@ -1,53 +0,0 @@ -{% if page.header.image contains "://" %} - {% capture img_path %}{{ page.header.image }}{% endcapture %} -{% else %} - {% capture img_path %}{{ page.header.image | absolute_url }}{% endcapture %} -{% endif %} - -{% if page.header.cta_url contains "://" %} - {% capture cta_path %}{{ page.header.cta_url }}{% endcapture %} -{% else %} - {% capture cta_path %}{{ page.header.cta_url | absolute_url }}{% endcapture %} -{% endif %} - -{% if page.header.overlay_image contains "://" %} - {% capture overlay_img_path %}{{ page.header.overlay_image }}{% endcapture %} -{% elsif page.header.overlay_image %} - {% capture overlay_img_path %}{{ page.header.overlay_image | absolute_url }}{% endcapture %} -{% endif %} - -{% if page.header.overlay_filter contains "rgba" %} - {% capture overlay_filter %}{{ page.header.overlay_filter }}{% endcapture %} -{% elsif page.header.overlay_filter %} - {% capture overlay_filter %}rgba(0, 0, 0, {{ page.header.overlay_filter }}){% endcapture %} -{% endif %} - -
- {% if page.header.overlay_color or page.header.overlay_image %} -
-

- {% if paginator and site.paginate_show_page_num %} - {{ site.title }}{% unless paginator.page == 1 %} {{ site.data.ui-text[site.locale].page | default: "Page" }} {{ paginator.page }}{% endunless %} - {% else %} - {{ page.title | default: site.title | markdownify | remove: "

" | remove: "

" }} - {% endif %} -

- {% if page.excerpt %} -

{{ page.excerpt | markdownify | remove: "

" | remove: "

" }}

- {% endif %} - {% if site.read_time and page.read_time %} -

{% include read-time.html %}

- {% endif %} - {% if page.header.cta_url %} -

{{ page.header.cta_label | default: site.data.ui-text[site.locale].more_label | default: "Learn More" }}

- {% endif %} -
- {% else %} - {{ page.title }} - {% endif %} - {% if page.header.caption %} - {{ page.header.caption | markdownify | remove: "

" | remove: "

" }}
- {% endif %} -
diff --git a/docs/_includes/page__hero_video.html b/docs/_includes/page__hero_video.html deleted file mode 100755 index 8586a95a2..000000000 --- a/docs/_includes/page__hero_video.html +++ /dev/null @@ -1,4 +0,0 @@ -{% capture video_id %}{{ page.header.video.id }}{% endcapture %} -{% capture video_provider %}{{ page.header.video.provider }}{% endcapture %} - -{% include video id=video_id provider=video_provider %} diff --git a/docs/_includes/page__taxonomy.html b/docs/_includes/page__taxonomy.html deleted file mode 100755 index 75c76c81d..000000000 --- a/docs/_includes/page__taxonomy.html +++ /dev/null @@ -1,7 +0,0 @@ -{% if site.tag_archive.type and page.tags[0] %} - {% include tag-list.html %} -{% endif %} - -{% if site.category_archive.type and page.categories[0] %} - {% include category-list.html %} -{% endif %} \ No newline at end of file diff --git a/docs/_includes/paginator.html b/docs/_includes/paginator.html deleted file mode 100755 index cf49ae8a2..000000000 --- a/docs/_includes/paginator.html +++ /dev/null @@ -1,69 +0,0 @@ -{% if paginator.total_pages > 1 %} - -{% endif %} diff --git a/docs/_includes/post_pagination.html b/docs/_includes/post_pagination.html deleted file mode 100755 index 3b8b61686..000000000 --- a/docs/_includes/post_pagination.html +++ /dev/null @@ -1,14 +0,0 @@ -{% if page.previous or page.next %} - -{% endif %} \ No newline at end of file diff --git a/docs/_includes/read-time.html b/docs/_includes/read-time.html deleted file mode 100755 index df88d5292..000000000 --- a/docs/_includes/read-time.html +++ /dev/null @@ -1,15 +0,0 @@ -{% assign words_per_minute = site.words_per_minute | default: 200 %} - -{% if post.read_time %} - {% assign words = post.content | strip_html | number_of_words %} -{% elsif page.read_time %} - {% assign words = page.content | strip_html | number_of_words %} -{% endif %} - -{% if words < words_per_minute %} - {{ site.data.ui-text[site.locale].less_than | default: "less than" }} 1 {{ site.data.ui-text[site.locale].minute_read | default: "minute read" }} -{% elsif words == words_per_minute %} - 1 {{ site.data.ui-text[site.locale].minute_read | default: "minute read" }} -{% else %} - {{ words | divided_by:words_per_minute }} {{ site.data.ui-text[site.locale].minute_read | default: "minute read" }} -{% endif %} \ No newline at end of file diff --git a/docs/_includes/scripts.html b/docs/_includes/scripts.html deleted file mode 100755 index 844de82dd..000000000 --- a/docs/_includes/scripts.html +++ /dev/null @@ -1,4 +0,0 @@ - - -{% include analytics.html %} -{% include /comments-providers/scripts.html %} diff --git a/docs/_includes/seo.html b/docs/_includes/seo.html deleted file mode 100755 index 4223fb19b..000000000 --- a/docs/_includes/seo.html +++ /dev/null @@ -1,147 +0,0 @@ - -{% if site.url %} - {% assign seo_url = site.url | append: site.baseurl %} -{% endif %} -{% assign seo_url = seo_url | default: site.github.url %} - -{% if page.title %} - {% assign seo_title = page.title | append: " " | append: site.title_separator | append: " " | append: site.title %} -{% endif %} - -{% if seo_title %} - {% assign seo_title = seo_title | markdownify | strip_html | strip_newlines | escape_once %} -{% endif %} - -{% if site.url %} - {% assign canonical_url = page.url | replace: "index.html", "" | prepend: site.url %} -{% endif %} - -{{ seo_title | default: site.title }}{% if paginator %}{% unless paginator.page == 1 %} {{ site.title_separator }} {{ site.data.ui-text[site.locale].page | default: "Page" }} {{ paginator.page }}{% endunless %}{% endif %} - -{% assign seo_description = page.description | default: page.excerpt | default: site.description %} -{% if seo_description %} - {% assign seo_description = seo_description | markdownify | strip_html | strip_newlines | escape_once %} -{% endif %} - - - -{% assign seo_author = page.author | default: page.author[0] | default: site.author.name %} -{% if seo_author %} - {% if seo_author.twitter %} - {% assign seo_author_twitter = seo_author.twitter %} - {% else %} - {% if site.data.authors and site.data.authors[seo_author] %} - {% assign seo_author_twitter = site.data.authors[seo_author].twitter %} - {% else %} - {% assign seo_author_twitter = seo_author %} - {% endif %} - {% endif %} - {% assign seo_author_twitter = seo_author_twitter | replace: "@", "" %} -{% endif %} - - - - - - - -{% if seo_url %} - - -{% endif %} - -{% if page.excerpt %} - -{% endif %} - -{% if site.twitter.username %} - - - - - - {% if page.header.image %} - - - {% else %} - - {% if page.header.teaser %} - - {% elsif site.og_image %} - - {% endif %} - {% endif %} - - {% if seo_author_twitter %} - - {% endif %} -{% endif %} - -{% if site.facebook %} - {% if site.facebook.publisher %} - - {% endif %} - - {% if site.facebook.app_id %} - - {% endif %} -{% endif %} - -{% if page.header.image %} - -{% elsif page.header.overlay_image %} - -{% elsif page.header.teaser %} - -{% elsif site.og_image %} - -{% endif %} - -{% if page.date %} - - -{% endif %} - -{% if paginator.previous_page %} - -{% endif %} -{% if paginator.next_page %} - -{% endif %} - -{% if site.og_image %} - -{% endif %} - -{% if site.social %} - -{% endif %} - -{% if site.google_site_verification %} - -{% endif %} -{% if site.bing_site_verification %} - -{% endif %} -{% if site.alexa_site_verification %} - -{% endif %} -{% if site.yandex_site_verification %} - -{% endif %} - diff --git a/docs/_includes/sidebar.html b/docs/_includes/sidebar.html old mode 100755 new mode 100644 index d2661c385..5410415cd --- a/docs/_includes/sidebar.html +++ b/docs/_includes/sidebar.html @@ -1,23 +1,30 @@ -{% if page.author_profile or layout.author_profile or page.sidebar %} -