From 1cac864100addbd3c4d9f7a218c38682f56de4e8 Mon Sep 17 00:00:00 2001 From: bill bittner Date: Thu, 15 Mar 2018 12:05:39 -0700 Subject: [PATCH] updated Seo component to pull site info from state --- config/siteConfig.js | 9 ++-- .../{Preview => PublishPreview}/index.jsx | 6 +-- react/components/SEO/index.jsx | 42 ++++++----------- react/components/SEO/view.jsx | 38 +++++++++++++++ react/containers/Dropzone/view.jsx | 4 +- react/reducers/site.js | 23 +++++++--- react/utils/canonicalLink.js | 30 +++++------- react/utils/metaTags.js | 46 +++++++++---------- react/utils/pageTitle.js | 8 ++-- 9 files changed, 114 insertions(+), 92 deletions(-) rename react/components/{Preview => PublishPreview}/index.jsx (93%) create mode 100644 react/components/SEO/view.jsx diff --git a/config/siteConfig.js b/config/siteConfig.js index c471b48e..22732547 100644 --- a/config/siteConfig.js +++ b/config/siteConfig.js @@ -3,18 +3,19 @@ function SiteConfig () { googleId: 'default', }; this.assetDefaults = { - title : 'Spee.ch', + description: 'An asset published on Spee.ch', thumbnail : 'https://spee.ch/assets/img/video_thumb_default.png', - description: 'Open-source, decentralized image and video sharing.', + title : 'Spee.ch', }; this.auth = { sessionKey: 'default', }; this.details = { + description: 'Open-source, decentralized image and video sharing.', + host : 'default', port : 3000, title : 'Spee.ch', - host : 'default', - description: 'Open-source, decentralized image and video sharing.', + twitter : '@spee_ch', }; this.publishing = { additionalClaimAddresses: [], diff --git a/react/components/Preview/index.jsx b/react/components/PublishPreview/index.jsx similarity index 93% rename from react/components/Preview/index.jsx rename to react/components/PublishPreview/index.jsx index e8c3b2f7..3699ba4e 100644 --- a/react/components/Preview/index.jsx +++ b/react/components/PublishPreview/index.jsx @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; -class Preview extends React.Component { +class PublishPreview extends React.Component { constructor (props) { super(props); this.state = { @@ -53,10 +53,10 @@ class Preview extends React.Component { } }; -Preview.propTypes = { +PublishPreview.propTypes = { dimPreview: PropTypes.bool.isRequired, file : PropTypes.object.isRequired, thumbnail : PropTypes.object, }; -export default Preview; +export default PublishPreview; diff --git a/react/components/SEO/index.jsx b/react/components/SEO/index.jsx index 555777d6..8a004ff6 100644 --- a/react/components/SEO/index.jsx +++ b/react/components/SEO/index.jsx @@ -1,32 +1,16 @@ -import React from 'react'; -import Helmet from 'react-helmet'; -import PropTypes from 'prop-types'; +import { connect } from 'react-redux'; +import View from './view'; -import { createPageTitle } from 'utils/pageTitle'; -import { createMetaTags } from 'utils/metaTags'; -import { createCanonicalLink } from 'utils/canonicalLink'; - -class SEO extends React.Component { - render () { - let { pageTitle, asset, channel, pageUri } = this.props; - pageTitle = createPageTitle(pageTitle); - const metaTags = createMetaTags(asset, channel); - const canonicalLink = createCanonicalLink(asset, channel, pageUri); - return ( - - ); - } +const mapStateToProps = ({ site }) => { + const { defaultDescription, defaultThumbnail, description: siteDescription, host: siteHost, title: siteTitle, twitter: siteTwitter } = site; + return { + defaultDescription, + defaultThumbnail, + siteDescription, + siteHost, + siteTitle, + siteTwitter, + }; }; -SEO.propTypes = { - pageTitle: PropTypes.string, - pageUri : PropTypes.string, - channel : PropTypes.object, - asset : PropTypes.object, -}; - -export default SEO; +export default connect(mapStateToProps, null)(View); diff --git a/react/components/SEO/view.jsx b/react/components/SEO/view.jsx new file mode 100644 index 00000000..7d476367 --- /dev/null +++ b/react/components/SEO/view.jsx @@ -0,0 +1,38 @@ +import React from 'react'; +import Helmet from 'react-helmet'; +import PropTypes from 'prop-types'; + +import { createPageTitle } from 'utils/pageTitle'; +import { createMetaTags } from 'utils/metaTags'; +import { createCanonicalLink } from 'utils/canonicalLink'; + +class SEO extends React.Component { + render () { + // props from state + const { defaultDescription, defaultThumbnail, siteDescription, siteHost, siteTitle, siteTwitter } = this.props; + // props from parent + const { asset, channel, pageUri } = this.props; + let { pageTitle } = this.props; + // create page title, tags, and canonical link + pageTitle = createPageTitle(siteTitle, pageTitle); + const metaTags = createMetaTags(siteDescription, siteHost, siteTitle, siteTwitter, asset, channel, defaultDescription, defaultThumbnail); + const canonicalLink = createCanonicalLink(asset, channel, pageUri, siteHost); + // render results + return ( + + ); + } +}; + +SEO.propTypes = { + pageTitle: PropTypes.string, + pageUri : PropTypes.string, + channel : PropTypes.object, + asset : PropTypes.object, +}; + +export default SEO; diff --git a/react/containers/Dropzone/view.jsx b/react/containers/Dropzone/view.jsx index a97b1ee6..7dbdeeab 100644 --- a/react/containers/Dropzone/view.jsx +++ b/react/containers/Dropzone/view.jsx @@ -1,6 +1,6 @@ import React from 'react'; import { validateFile } from 'utils/file'; -import Preview from 'components/Preview'; +import PublishPreview from 'components/PublishPreview'; class Dropzone extends React.Component { constructor (props) { @@ -87,7 +87,7 @@ class Dropzone extends React.Component {
{this.props.file ? (
- { - if (!page) { - return `${host}`; - }; - return `${host}/${page}`; +const createBasicCanonicalLink = (page, siteHost) => { + return `${siteHost}/${page}`; }; -const createAssetCanonicalLink = (asset) => { +const createAssetCanonicalLink = (asset, siteHost) => { let channelName, certificateId, name, claimId; if (asset.claimData) { ({ channelName, certificateId, name, claimId } = asset.claimData); }; if (channelName) { - return `${host}/${channelName}:${certificateId}/${name}`; + return `${siteHost}/${channelName}:${certificateId}/${name}`; }; - return `${host}/${claimId}/${name}`; + return `${siteHost}/${claimId}/${name}`; }; -const createChannelCanonicalLink = (channel) => { +const createChannelCanonicalLink = (channel, siteHost) => { const { name, longId } = channel; - return `${host}/${name}:${longId}`; + return `${siteHost}/${name}:${longId}`; }; -export const createCanonicalLink = (asset, channel, page) => { +export const createCanonicalLink = (asset, channel, page, siteHost) => { if (asset) { - return createAssetCanonicalLink(asset); + return createAssetCanonicalLink(asset, siteHost); } if (channel) { - return createChannelCanonicalLink(channel); + return createChannelCanonicalLink(channel, siteHost); } - if (page) { - return createBasicCanonicalLink(page); - } - return createBasicCanonicalLink(); + return createBasicCanonicalLink(page, siteHost); }; diff --git a/react/utils/metaTags.js b/react/utils/metaTags.js index 56d78d2c..215b8253 100644 --- a/react/utils/metaTags.js +++ b/react/utils/metaTags.js @@ -1,5 +1,3 @@ -const { details: { title, host, description }, assetDefaults: { thumbnail: defaultThumbnail, description: defaultDescription } } = require('../../config/siteConfig.js'); - const determineOgThumbnailContentType = (thumbnail) => { if (thumbnail) { const fileExt = thumbnail.substring(thumbnail.lastIndexOf('.')); @@ -20,35 +18,35 @@ const determineOgThumbnailContentType = (thumbnail) => { return ''; }; -const createBasicMetaTags = () => { +const createBasicMetaTags = (siteHost, siteDescription, siteTitle, siteTwitter) => { return [ - {property: 'og:title', content: title}, - {property: 'og:url', content: host}, - {property: 'og:site_name', content: title}, - {property: 'og:description', content: description}, - {property: 'twitter:site', content: '@spee_ch'}, + {property: 'og:title', content: siteTitle}, + {property: 'og:url', content: siteHost}, + {property: 'og:site_name', content: siteTitle}, + {property: 'og:description', content: siteDescription}, + {property: 'twitter:site', content: siteTwitter}, {property: 'twitter:card', content: 'summary'}, ]; }; -const createChannelMetaTags = (channel) => { +const createChannelMetaTags = (siteTitle, siteHost, siteTwitter, channel) => { const { name, longId } = channel; return [ - {property: 'og:title', content: `${name} on ${title}`}, - {property: 'og:url', content: `${host}/${name}:${longId}`}, - {property: 'og:site_name', content: title}, - {property: 'og:description', content: `${name}, a channel on ${title}`}, - {property: 'twitter:site', content: '@spee_ch'}, + {property: 'og:title', content: `${name} on ${siteTitle}`}, + {property: 'og:url', content: `${siteHost}/${name}:${longId}`}, + {property: 'og:site_name', content: siteTitle}, + {property: 'og:description', content: `${name}, a channel on ${siteTitle}`}, + {property: 'twitter:site', content: siteTwitter}, {property: 'twitter:card', content: 'summary'}, ]; }; -const createAssetMetaTags = (asset) => { +const createAssetMetaTags = (siteHost, siteTitle, siteTwitter, asset, defaultDescription, defaultThumbnail) => { const { claimData } = asset; const { contentType } = claimData; - const embedUrl = `${host}/${claimData.claimId}/${claimData.name}`; - const showUrl = `${host}/${claimData.claimId}/${claimData.name}`; - const source = `${host}/${claimData.claimId}/${claimData.name}.${claimData.fileExt}`; + const embedUrl = `${siteHost}/${claimData.claimId}/${claimData.name}`; + const showUrl = `${siteHost}/${claimData.claimId}/${claimData.name}`; + const source = `${siteHost}/${claimData.claimId}/${claimData.name}.${claimData.fileExt}`; const ogTitle = claimData.title || claimData.name; const ogDescription = claimData.description || defaultDescription; const ogThumbnailContentType = determineOgThumbnailContentType(claimData.thumbnail); @@ -56,11 +54,11 @@ const createAssetMetaTags = (asset) => { const metaTags = [ {property: 'og:title', content: ogTitle}, {property: 'og:url', content: showUrl}, - {property: 'og:site_name', content: title}, + {property: 'og:site_name', content: siteTitle}, {property: 'og:description', content: ogDescription}, {property: 'og:image:width', content: 600}, {property: 'og:image:height', content: 315}, - {property: 'twitter:site', content: '@spee_ch'}, + {property: 'twitter:site', content: siteTwitter}, ]; if (contentType === 'video/mp4' || contentType === 'video/webm') { metaTags.push({property: 'og:video', content: source}); @@ -85,12 +83,12 @@ const createAssetMetaTags = (asset) => { return metaTags; }; -export const createMetaTags = (asset, channel) => { +export const createMetaTags = (siteDescription, siteHost, siteTitle, siteTwitter, asset, channel, defaultDescription, defaultThumbnail) => { if (asset) { - return createAssetMetaTags(asset); + return createAssetMetaTags(siteHost, siteTitle, siteTwitter, asset, defaultDescription, defaultThumbnail); }; if (channel) { - return createChannelMetaTags(channel); + return createChannelMetaTags(siteHost, siteTitle, siteTwitter, channel); }; - return createBasicMetaTags(); + return createBasicMetaTags(siteDescription, siteHost, siteTitle, siteTwitter); }; diff --git a/react/utils/pageTitle.js b/react/utils/pageTitle.js index 4a510b36..2b577c0b 100644 --- a/react/utils/pageTitle.js +++ b/react/utils/pageTitle.js @@ -1,8 +1,6 @@ -const { details: { title } } = require('../../config/siteConfig.js'); - -export const createPageTitle = (pageTitle) => { +export const createPageTitle = (siteTitle, pageTitle) => { if (!pageTitle) { - return `${title}`; + return `${siteTitle}`; } - return `${title} - ${pageTitle}`; + return `${siteTitle} - ${pageTitle}`; };