Gatsby: أضف دليلًا رسميًا لتدويل المواقع الإلكترونية باستخدام Gatsby

تم إنشاؤها على ٤ فبراير ٢٠١٨  ·  74تعليقات  ·  مصدر: gatsbyjs/gatsby

بعد أن رأيت ردود الفعل على تعليقي على قضية أخرى ، قررت فتح هذا الموضوع.

أعتقد أن i18n أصعب بكثير مما ينبغي. لم أتمكن من العثور على أي وثائق رسمية أو مكون إضافي لتدويل المحتوى على مواقع الويب التي يصنعها غاتسبي. صادفت jsLingui ، والذي يبدو أنه يحل معظم المشكلات ، ولكن لا توجد أدلة حتى الآن حول الاحتفاظ بملفات / صفحات markdown بلغات مختلفة.

documentation

التعليق الأكثر فائدة

مرحبًا يا رفاق ، لقد مر عام تقريبًا 😅

لقد قمت مؤخرًا بإصدار ملحق gatsby الجديد gatsby -plugin-intl الذي يجعل موقع gatsby الخاص بك بسهولة كإطار عمل تدويل خارج الصندوق.

العرض التوضيحي: https://gatsby-starter-default-intl.netlify.com

  • إطار تدويل خارج الصندوق مدعوم من react-intl

  • دعم إعادة التوجيه التلقائي بناءً على لغة المستخدم المفضلة في المتصفح

  • دعم مسارات URL متعددة اللغات في مكون صفحة واحدة. هذا يعني أنه ليس عليك إنشاء صفحات منفصلة مثل pages/en/index.js أو pages/ko/index.js .

  • كما اقترح البعض منكم أعلاه ، فهي الآن تجمع اللغة الحالية فقط أثناء وقت الإنشاء.

أيضًا ، أود أن أذكر أن العديد من أمثلة / مبتدئين i18n يتم تقديمها بالفعل من جانب العميل. أفضل طريقة للتحقق مما إذا كان التطبيق يتم عرضه على أنه SSR هو عرض الكود المصدري والتحقق مما إذا كانت النصوص المترجمة موجودة أم لا. يرجى التحقق مرة أخرى من هذا الأمر عندما تقوم بتدويل موقع الويب الخاص بك على gatsby لتحسين محركات البحث.

ال 74 كومينتر

توجد هذه المقالة حول استخدام i18next مع GatsbyJS ، وهي الطريقة الأكثر تقدمًا بالنسبة لي حتى الآن.

لكني لا أشعر أن i18next هي "الطريقة الثابتة".

حول منشور المدونة ، كان لدي هذه الأسئلة / التحفظات:
https://twitter.com/semdubois/status/930389055388508160

يوجد https://github.com/angeloocana/gatsby-plugin-i18n ولكن له العديد من القيود ولا يتلقى الكثير من النشاط / الاهتمام. قد يكون من المفيد نقله داخل مستودع Gatsby. أنا أيضا أحب حل موحد مناسب.

لقد عثرت على js lingui أيضًا ويبدو أنها واعدة ، خاصة مع الإصدار 2 للتو.

أنا أيضا أحاول معرفة ذلك. يعد استخدام طريقة i18next في المنشور هو الأكثر ملاءمة وبديهية ، لكن لدي سؤالان ....

  1. كيف يمكنني دمج ملفات markdown مختلفة للغات مثل حل gatsby-plugin-i18n؟

  2. هل يتخلى هذا تمامًا عن العرض الثابت للمحتوى؟

تضمين التغريدة

سأكتب ملخصًا قصيرًا عن كيفية تعاملنا مع الأمر في الوقت الحالي باستخدام react-intl . هذا التطبيق ليس قيد الإنتاج حتى الآن ، لذلك قد لا نزال نجد بعض المشكلات في هذا الإعداد ، ولكن يبدو أنه يعمل بشكل جيد حتى الآن.

نحتفظ بجميع محتوياتنا تقريبًا (التي تم ترحيلها من مدونة Wordpress الخاصة بنا) في gatsby-source-contentful plugin لجلب هذه البيانات ، ومع ذلك ، في وقت سابق كنا نجلب هذه البيانات ونحولها إلى ملفات JSON بأنفسنا واستخدمنا gatsby-source-filesystem plugin (استخدمنا بنية المجلد مثل /en/blog/... ، /de/blog/... ) ، لذلك لا يهم حقًا ما إذا كان الشخص يستخدم Contentful أم لا ، طالما أن كل عقدة تعرف موقعها.

لدينا أيضًا بعض النصوص مثل تسميات الأزرار أو بعض الروابط أو المحتوى الثابت الذي لا يأتي من Contentful ، ولكن تمت ترجمته في Transifex بدلاً من ذلك ومزامنته مع ملفات JSON المخزنة في الريبو. بالنسبة لهذا الجزء ، احتجنا إلى استخدام بعض مكتبات i18n وقررنا استخدام react-intl ، فقط لأنني أعرفها بالفعل وأعرف أنها تتعامل مع تنسيق التاريخ والأرقام أيضًا. إليك كيفية إعداده: https://github.com/gatsbyjs/gatsby/issues/3830#issuecomment -362710469. نستخدم بعد ذلك على سبيل المثال intl.formatMessage عند إنشاء العلامات الوصفية ومكونات <FormattedMessage /> و <FormattedDate /> إلخ في القوالب.

szimek إذا كنت فلديك react-intl تتعامل مع ترجمة نص المكون أثناء وجود المنشورات في مسارات مشفرة أسفل دليل الصفحات؟

هذا يعني أن المسارات المشفرة هي الوحيدة التي يتم عرضها بشكل ثابت؟ ويتم تقديم الترجمات بين المكونات i18n ديناميكيًا؟

deltaskelta لست متأكدًا من فهمي لسؤالك.

ليس لدينا أي توجيه مخصص من جانب العميل (كما هو موضح هنا على سبيل المثال) في الوقت الحالي ، فقط الصفحات المنشأة بشكل ثابت. عند إنشاء صفحة post (نقوم أيضًا بإنشاء صفحات خاصة بلغة محددة ومرقمة باللغة index و category باستخدام نسخة معدلة قليلاً من gatsby-pagination plugin) ، نحن باستخدام الكود التالي:

posts.edges.map(({ node }) => {
  const id = node.contentfulid;
  const locale = node.node_locale;

  return createPage({
    path: `/${locale}/blog/posts/${id}`,
    layout: locale,
    component: path.resolve('./src/templates/post-page.jsx'),
    context: {
      id,
      locale,
    },
  });
});

حتى في حالة تعطيل JS ، يتم عرض كل المحتوى ، بما في ذلك العلامات الوصفية ، باللغة الصحيحة.

من جانبنا ، نحن نستخدم i18next مع بعض التعديلات

المبادئ الرئيسية هي كما يلي:

  • اللغات متاحة كملفات .json وانتقلت ببساطة إلى الدليل /dist/ أثناء الإنشاء.
  • نحن نعمل على صفحة واحدة ستنتج العديد من الإصدارات الثابتة مثل اللغات المتوفرة لدينا ، باستخدام onCreatePage (في gatsby-node.js ).
  • تتمركز معلومات الصفحات (مثل اسم المسار) في ملف واحد.

لغات

تم تجميع الترجمات في الغالب حسب الصفحة ، مع مساحة اسم واحدة (= ملف JSON) لكل صفحة + ملف عام واحد (للنصوص المشتركة مثل الرأس / التذييل).

|- src/
  |- locales/
    |- en/
      |- foo.json
      |- bar.json
    |- fr/
      |- foo.json
      |- bar.json

للأسف ، لا يوجد إعادة تحميل ساخنة على التعديلات المحلية 👎

i18next

تتم تهيئة i18next بالتكوين التالي:

import i18n from "i18next";
import Backend from "i18next-xhr-backend";
import { reactI18nextModule } from "react-i18next";
import config from "config";  // Our custom configurations env-specifics

const NAMESPACES = [
  "foo",
  "bar",
  ...
];

export default function createI18n() {
  const options = {
    fallbackLng   : false,
    whitelist     : ["en", "fr"],
    ns            : NAMESPACES,
    debug         : config.debug,
    interpolation : {
      escapeValue : false
    },
    react         : {
      wait : true
    },
    backend       : {
      loadPath : `${config.pathPrefix}locales/{{lng}}/{{ns}}.json`
    },
    parseMissingKeyHandler : () => "",  // Display an empty string when missing/loading key
  };

  return i18n
    .use(Backend)
    .use(reactI18nextModule)
    .init(options);
}

معلومات الصفحات

قبل إنشاء جميع إصدارات i18n لصفحاتنا ، نحتاج إلى معرفة بعض المعلومات التي قمنا بتجميعها في ملف pagesInfos.js :

module.exports = {
  index : {
    id          : "index",
    namespace   : "home",
    path        : {
      fr : "/",
      en : "/en/"
    }
  },
  projects : {
    id          : "projects",
    namespace   : "projects",
    path        : {
      fr : "/nos-clients/",
      en : "/en/our-clients/"
    }
  },
  // etc...

حيث تكون المفاتيح هي أسماء ملفات الصفحات ، وتكون مساحات الأسماء هي أسماء الملفات المحلية . يمكن أن يكونوا مختلفين 🚨

في هذه الحالة:

|- src/
  |- pages/
    |- index.js
    |- projects.js
  |- locales/
    |- en/
      |- home.json
      |- projects.json
    |- fr/
      |- home.json
      |- projects.json

وأين المسار هو أسماء المسار لإصداراتنا المستقبلية (اللغات) من صفحاتنا.

بناء الصفحات

مع نفس المثال أعلاه ، هدفنا هنا هو إنشاء نسخة FR + EN من الصفحة الرئيسية وصفحات المشروع.

لتحقيق ذلك ، أنشأنا وظيفة مخصصة:

/**
 * Generate a custom page informations
 * <strong i="15">@param</strong>  {Object} defaultInfos  Default informations generated by Gatsby
 * <strong i="16">@return</strong> {Object}               Customized page object
 */
function generatePagesInfos(defaultInfos) {
  const pageId = defaultInfos.jsonName.slice(0, -5);  // NOTE: Get pageId from "pageName.json"
  const pageInfos = pagesInfos[pageId];

  const pageFR = {
    ...defaultInfos,
    context : {
      pageId      : pageInfos.id,
      namespace   : pageInfos.namespace,
      language    : "fr"
    },
    path : pageInfos.path.fr
  };

  const pageEN = {
    ...defaultInfos,
    context : {
      pageId      : pageInfos.id,
      namespace   : pageInfos.namespace,
      language    : "en"
    },
    path : pageInfos.path.en
  };

  return [pageFR, pageEN];
}

سيتم استخدام هذا المساعد بعد ذلك أثناء ربط onCreatePage ، وتحديد كل صفحة عبر regex:

exports.onCreatePage = async ({ page, boundActionCreators }) => {
  const { createPage, deletePage } = boundActionCreators;

  return new Promise((resolve, reject) => {

    if (page.path.match(page.path.match(/^\/$/))) {
      const i18nPages = generatePagesInfos(page);
      deletePage(page);                         // Remove old default page
      i18nPages.map(page => createPage(page));  // Create custom i18n pages
    }

    if (page.path.match(/^\/projects\/?$/)) {
      const i18nPages = generatePagesInfos(page);
      deletePage(page);
      i18nPages.map(page => createPage(page));
    }

    // etc...

    resolve();
  });
}

لدينا الآن نسختان من كل صفحة ، مع اسم مسار مخصص (من ملف معلومات صفحاتنا). ربما لاحظت أننا نقوم بتمرير معلومات language لكل صفحة عبر pathContext . سيتم استخدام هذه القيمة في كل صفحة لعرض اللغة الصحيحة.

اعرض اللغة الصحيحة

نحن نستخدم فئة React للصفحات ، حيث يعرف مصمم الديكور التالي تلقائيًا لغة الصفحة الحالية ويقوم بتحديث i18n إذا لزم الأمر:

import React from "react";
import PropTypes from "prop-types";
import { i18n } from "context";    // Our custom context

/**
 * <strong i="10">@returns</strong> {React.PureComponent} Component with locales as proptypes
 */
export default function setLanguageFromPage() {

  return WrappedComponent => (
    class extends React.PureComponent {

      static propTypes = {
        pathContext : PropTypes.shape({
          language : PropTypes.string.isRequired
        })
      }

      componentDidMount() {
        const currentLanguage = i18n.language;
        const pageLanguage = this.props.pathContext.language;

        // First request
        if (!currentLanguage) {
          i18n.language = pageLanguage;
        }

        // Only update on language change
        if (currentLanguage !== pageLanguage) {
          i18n.changeLanguage(pageLanguage);
        }
      }

      render() {
        return <WrappedComponent {...this.props} />;
      }

    }
  );

}

ثم اتصل به على الصفحات:

@setLanguageFromPage()
export default class ProjectsPage extends React.PureComponent {
// ...

Pfew ، كل ما عليك فعله الآن هو استخدام وظيفة الترجمة في i18next.

استنتاج

👍 ملف مصدر واحد يقوم بإنشاء العديد من الإصدارات حسب الحاجة أثناء الإنشاء
👍 من السهل إدارة إخراج الصفحات
بعض الجهود في البداية ، ولكن بعد ذلك كل شيء بسيط

👎 لا يوجد إعادة تحميل ساخنة للمواقع

أشعر أنها ليست "طريقة الحياة الثابتة" حقًا ... ولكن هذا أفضل ما تمكنا من الحصول عليه في الوقت الحالي.

أود أن أرى رأيك في هذا ، وكيف تديرون ذلك يا رفاق.

ملاحظة. Pokeszimek ، هذا ما أردت أن

لقد كنت أستخدم @ angeloocana https://github.com/angeloocana/gatsby-plugin-i18n + React-intl وهو ليس معقدًا مثل الطرق المذكورة أعلاه ، ولكن هناك بعض القيود (انظر مشكلات إعادة الشراء) وأنا لست سعيدًا جدًا بشأن React-intl. أحب أن أجرب https://github.com/lingui/js-lingui @ tricoder42 ، لم يكن لدي الوقت.

monsieurnebo ما هو الهدف من تشغيل deletePage قبل createPage ؟ يعجبني الحل الذي قدمته وقد حاولت تنفيذه ، لكن لدي بعض الأخطاء.

  • إما أن أحصل على pathContext.language غير صحيح بدون استخدام deletePage

  • أو يظهر لي خطأ في الإصدار عندما أقوم بتضمين deletePage مثل المثال الخاص بك. (تقول TypeError: Cannot read property 'id' of undefined عندما يصل الإصدار إلى المرحلة run graphql queries )

هذا هو أفضل حل رأيته حتى الآن.

deltaskelta سعيد لرؤيتك مثل ذلك!

يستخدم deletePage لإلغاء إنشاء الصفحة الافتراضية بواسطة Gatsby. إذا لم يكن لإضافة هذا، سوف تحصل الصفحات المخصصة، وواحد الافتراضية.

تحقق من دليل public الخاص بك مع وبدون هذا السطر ، ستكتشف الفرق ؛)

حول أخطائك ، من الصعب تخمينها بدون رمز. هل يمكنك إنشاء مستودع برمزك؟ أود إلقاء نظرة عليه بعد ذلك.

تحرير: هل أنت مهتم بمثال ؟

أوه ، لم يكن له علاقة باستدعاء deletePage. كانت مشكلة عدم نسخ كائن الصفحات لأنني قمت بتعديل المثال الخاص بك. دائمًا ما أتعثر مع نسخ الكائن بعد الابتعاد عن js لفترة ؛)

monsieurnebo لقد كنت قدمته ويبدو أنك لا تزال بحاجة إلى جافا سكريبت لتحميل الإعدادات المحلية من ملفات json ، فهل هذا صحيح؟ علاوة على ذلك ، يبدو أن جميع المكونات المغلفة بـ react-i18next HOC تحتاج إلى جافا سكريبت لعرض أي شيء في المكون ...

هل يمكنك تأكيد ما إذا كانت هذه هي الطريقة التي تعمل بها من جانبك؟

تحرير: راجع للشغل فاتني ذكر أحد الأمثلة ، إذا كان لديك الوقت ، فأنا أحب أن أرى مثالاً كاملاً.

deltaskelta سأجعل مثالاً عندما يكون لدي بعض وقت الفراغ :)

monsieurnebo هل يمكنك تأكيد أن طريقتك لا تعرض السلاسل بشكل ثابت في html وتتطلب جافا سكريبت؟

نعم ، هذا هو السبب في أنها ليست "طريقة الحياة الثابتة" تمامًا 😐

أحب وجود مكون إضافي يقوم بإنشاء نص ثابت بدلاً من ذلك.

هم أرى. سيكون التصيير الثابت هو الطريقة التي أحتاجها للذهاب ...

كنت أفكر ، نظرًا لأن السياقات تم تمريرها بالفعل باستخدام اسم اللغة لمعظم الصفحات في gatsby-node ، فلن يكون من الصعب جدًا طلب مفاتيح الرسائل في استعلامات الرسم البياني لكل صفحة وتمريرها بهذه الطريقة ، لكنني أفضل استخدام أداة i18n بالكامل إن أمكن ...

szimek كيف يتم عرض الترجمات في react-intl في خطوة الإنشاء وعدم استخدام أي ملفات js؟

كما ذكرنا ، بقدر ما أستطيع أن أرى Gatsby-plugin-i18n يولد نصًا ثابتًا. هل تحققت من مثاله؟

deltaskelta حسنًا ، جميع الترجمات متاحة أثناء وقت gatsby-plugin-i18n حتى الآن ، لأنني أعمل مع Contentful ، وليس الملفات.

لم أقرأ التفاصيل ولكن هناك مناقشة (أو بالأحرى مونولوج) حول مجموعة مكونة غاتسبي-i18n + المحتوى هنا: https://github.com/angeloocana/gatsby-plugin-i18n/issues/31

szimek سأكون مهتمًا جدًا بمثال. sedubois أعرف أن gatsby-plugin-i18n يولد أيضًا نصًا ثابتًا ولكني لا أرى أين يحدث السحر المفقود في i18next من أجل إنشاء ملفات ثابتة تمامًا ...

أعتقد أنني قد أرى السبب الآن ... هل تقوم بتمرير react-intl الرسائل من خلال pathContext في gatsby-node أثناء العرض؟

تحرير: إذا كانت هذه هي الحالة (وهذا أمر منطقي) ، فإن مكتبة i18n المستخدمة "إلى حد ما" غير ذات صلة لأن المرء يمرر الرسائل عبر السياق ويعرضها بشكل ثابت وهو إعداد gatsby خالص ويتعامل i18n lib فقط مع الحالات الخاصة مثل التواريخ وصيغ الجمع مع js.

عند إجراء مزيد من الاختبارات لكل من i18next و react-intl ، يبدو أن ترجمة HOC لـ i18next تتطلب جافا سكريبت ليتم تحميلها ، لذلك حتى إذا تم تمرير الرسائل عبر السياق وعرضها بشكل ثابت ، أي استخدام للترجمة سيؤدي إلى عرض المكون بالكامل الذي يحتاج إلى جافا سكريبت ليتم تشغيله.

من ناحية أخرى ، يعرض المكون react-intl FormattedMessage رسالة افتراضية (والتي يمكن أن تستند إلى السياق الذي تم تمريره إليه) ويظهر بشكل ثابت في html عند الإنشاء.

حسب التصميم ، أعتقد أن التكامل الطبيعي لـ i18n سيكون مع React-intl إذا كنت تريد تحقيق ترجمات معروضة بشكل ثابت في HTML. إذا كنت قد أسأت فهم التدفق الذي تستخدمه يا رفاق ، فالرجاء تصحيحني

لدى mattferderer الفكرة الصحيحة هنا ، لكنني أعتقد أنها تحتاج إلى القليل من التغيير والتبديل. https://github.com/gatsbyjs/gatsby/issues/3830#issuecomment -362715706

يتم عرض التخطيطات قبل الصفحات ، لذلك بدون إنشاء تخطيطات متعددة ، لا توجد طريقة لتمرير الرسائل عبر السياق ، من الوظيفة createPages (صححني إذا كنت مخطئًا هنا). لذلك ، من أجل جعل i18n أسهل ، أعتقد أن التصميم يجب أن يستدعي فقط children() ومن ثم سيتم إنجاز التخطيطات المختلفة لكل تأثير من خلال جعل gatsby-node ينشئ مسارًا مختلفًا لكل لغة صفحات الفهرس من pages/index والتي يمكن أن تمرر الرسائل عبر السياق

تحرير: آسف للتجول ولكن كل شيء أصبح واضحًا واضطررت إلى تسجيله في مكان ما

تحرير 2: أنا مخطئ بالتأكيد أعلاه ، يجب أن تدخل الرؤوس والتذييلات في التخطيط ، ولا أعرف كيفية توصيل الرسائل إليهم دون إنشاء تخطيطات متعددة. الطريقة الأخرى الوحيدة التي يمكنني التفكير بها هي تقسيم عناوين url و regexing للغة ... ولكن هذا يبدو كشيء مخترق يجب القيام به

KyleAMathews مع v2 له تخطيط واحد فقط ، كيف يمكننا تمرير بيانات مثل رسائل i18n إلى مكون تخطيط الجذر من خلال السياق بناءً على المسار أو مجموعة من مفاتيح اللغة؟

إذا كان من الممكن القيام بذلك ، فسيكون من السهل تنفيذ i18n ، لكن لا يمكنني معرفة كيفية القيام بذلك دون عمل تخطيطات متعددة

deltaskelta إليك مثال على ما نقوم به: https://github.com/szimek/gatsby-react-intl-example. يوضح كيفية عرض المنشورات الفردية ، وكيفية إنشاء صفحة فهرس لكل لغة ، وكيفية استخدام مكونات react-intl ، وكيفية استخدام react-intl injectIntl HOC لتعيين عنوان (أو أي علامات وصفية أخرى) لصفحات الفهرس باستخدام مساعد intl.formatMessage إلخ.

الصفحات التي تم إنشاؤها هي:

  • /en
  • /en/hello-world
  • /pl
  • /pl/witaj-swiecie

في التطبيق الحقيقي ، نستخدم نسخة معدلة من gatsby-pagination ، لأن الإصدار الأصلي لا يدعم خيار التنسيق. قمنا أيضًا بتعيين حقل post_id لكل منشور يسمح لنا بالعثور على ترجمات نفس المنشور ، على سبيل المثال في حالة هذا التطبيق التجريبي ، سيكون لكلا المنشورين نفس post_id .

بالمناسبة. لقد أدركت للتو أننا سنحتاج على الأرجح إلى إنشاء خرائط مواقع منفصلة لكل لغة ، بحيث يعرف Swiftype (محرك البحث الذي نستخدمه) الصفحات التي حصلنا عليها.

deltaskelta باختصار سيكون لديك مكونات صفحة لكل لغة ومن ثم يكون لديك مكون تخطيط لكل لغة. إليك طريقة واحدة يمكنك القيام بذلك.

// French
import React from 'react'
import FrenchLayout from '../components/layouts/french'
import ImportantPage from '../components/pages/important-page'

export default ({ data }) => (
  <FrenchLayout>
    <ImportantPage {...data} />
  </FrenchLayout>
)

// French query here
// English
import React from 'react'
import EnglishLayout from '../components/layouts/english'
import ImportantPage from '../components/pages/important-page'

export default ({ data }) => (
  <EnglishLayout>
    <ImportantPage {...data} />
  </EnglishLayout>
)

// English query here

KyleAMathews هذه الملفات عبارة عن قوالب ، أليس كذلك؟ هل يعني ذلك أنه إذا كان لدي 3 أنواع من الصفحات و 7 لغات ، فسوف أحتاج إلى 21 نموذجًا؟ :)

ما سبق هو الطريقة المثلى للقيام بذلك. إذا لم يكن كل مكون من مكونات التخطيط مختلفًا ، فيمكنك دمجها في مكون تخطيط واحد ثم تبديل التخطيط بناءً على اللغة النشطة.

لم أقرأ التفاصيل ولكن هناك مناقشة (أو بالأحرى مونولوج) حول gatsby-plugin-i18n + contentful combo هنا: angeloocana / gatsby-plugin-i18n # 31

sedubois ، هاها ، نعم. ملخص: لقد نجحت في العمل وتضمنت إعادة الشراء المبدئي gatsby-starter-contentful-i18n في مستندات Gatsby عبر هذا العلاقات العامة: https://github.com/gatsbyjs/gatsby/pull/4138

مهتم بالحل الآخر أعلاه ، خاصةً كيفية مقارنته بالمكوِّن الإضافي للمجتمع: SEO ، إلخ.

mccrodp يبدو الحل الخاص بك مشابهًا جدًا لي ، والفرق الرئيسي هو أن gatsby-plugin-i18n لا يتطلب منك صراحة تمرير الخيار layout إلى createPage ، لكنه يفعل ذلك من أجلك خلف الكواليس. ومع ذلك ، لا يزال يستخدم تنسيقات متعددة ؛)

لقد اخترت اقتراح components/Layout يستخدم i18n lib وحذف مجلد تخطيط gatsby الخاص بي بالكامل. بهذه الطريقة ، يمكنني في gatsby-node صفحات للغات الخاصة بي ولديهم حق الوصول إلى كل شيء يمكن للصفحة الوصول إليه ، بما في ذلك المسارات.

يمكنني بعد ذلك تمرير الإعدادات المحلية مباشرة إلى مكون التخطيط الذي يمررها إلى i18n.

من غير الملائم إلى حد ما أن تضطر إلى التفاف كل مكون على مستوى الصفحة بالتخطيط ، ولكنه أدى إلى إزالة الكثير من الالتباس وتبسيط الكود الخاص بي كثيرًا.

مرحبًا deltaskelta ، هل لديك مثال على الحل الخاص بك؟ أرغب في معرفة ما إذا كان يمكن تعلم أي شيء منه للدفع إلى البرنامج الإضافي للمجتمع i18n. شكرا.

مشروعي بأكمله في حالة فوضوية في الوقت الحالي ولكن أعتقد أنه يمكنني وضع الأساسيات ...

  1. لا يوجد تخطيط - لأنه (إذا كنت أتذكر بشكل صحيح) ، يتم تشغيل التخطيط قبل المسارات أو أي شيء آخر كان مهمًا للغاية ، مما منعني من إعطائه كائنات الرسائل المناسبة ...

  2. قم بتغذية messages و locale في gatsby-node خلال السياق ...

exports.onCreatePage = ({ page, boundActionCreators }) => {
  const { createPage, deletePage } = boundActionCreators;

  if (page.path.includes('404')) {
    return; // no need for localized 404 pages
  }

  return new Promise(resolve => {
    // if it is not the app page then I need localized static pages
    const pages = localizedPages(page);
    deletePage(page);
    pages.map(page => createPage(page));

    resolve();
  });
};

// to be passed to the localized pages so it can calculate the matchPath
const getMatchPath = lang => {
  return `${locales[lang]['path']}/app/:path`;
};

// this is a helper function that makes pages in each language.
const localizedPages = (page, matchPathFunc) => {
  var pages = [];
  Object.keys(locales).map(lang => {
    const path = locales[lang]['path'] + page.path;

    pages.push({
      ...page,
      path: path,
      matchPath: matchPathFunc ? matchPathFunc(lang) : undefined,
      context: {
        locale: lang,
        messages: locales[lang],
        pathRegex: `/.pages${page.path}./` // so pages can match markdown in their dir
      }
    });
  });

  return pages;
};
  1. الآن قم بإنشاء مكون تخطيط عام يجب استدعاؤه في كل مكون على مستوى الصفحة ...
// this is the main entrypoint for the layout to the site
const GlobalLayout = ({ locale, children, path }) => {
  const theme = getTheme();
  return (
    <MuiThemeProvider theme={theme}>
      <CssBaseline>
        <IntlProvider locale={locale} messages={locales[locale]}>
          <div>
            <Header locale={locale} messages={locales[locale]} path={path} />
            {children}
          </div>
        </IntlProvider>
      </CssBaseline>
    </MuiThemeProvider>
  );
};
  1. قم باستدعاء مكون التخطيط العام بمكونات مستوى الصفحة الخاصة بك والتي لها الإعدادات المحلية المناسبة والرسائل التي تم تمريرها من السياق
const BlogPost = ({ data, pathContext, location }) => {
  const { locale } = pathContext;
  return (
    <GlobalLayout locale={locale} path={location.pathname}>
      <FullWidth>
        <h1>{data.markdownRemark.frontmatter.title}</h1>
        <h3>{data.markdownRemark.frontmatter.date}</h3>
        <div dangerouslySetInnerHTML={{ __html: data.markdownRemark.html }} />
      </FullWidth>
    </GlobalLayout>
  );
};

يجب أن أقوم بتنظيف وإعادة تنظيم هذا الرمز لأنني قمت بذلك سريعًا لإثبات أنه يمكن أن يعمل وسأعيد زيارته لاحقًا ... آمل أن يمنحك هذا جوهره

لقد أنشأت كاتب gatsby الذي يستخدم js-lingui لترجمة الرسائل:
https://github.com/dcroitoru/gatsby-starter-i18n-lingui

في التطبيق الحقيقي ، نستخدم نسخة معدلة من gatsby-pagination ، لأن الإصدار الأصلي لا يدعم خيار التنسيق. قمنا أيضًا بتعيين حقل post_id لكل منشور يسمح لنا بالعثور على ترجمات لنفس المنشور ، على سبيل المثال في حالة هذا التطبيق التجريبي ، سيكون لكلا المنشورين نفس post_id.

szimek هل هناك أي فرصة لمشاركة ترقيم صفحات gatsby المعدلة؟ سأكون حريصًا جدًا على رؤيته لأنني أواجه مشكلة مماثلة بنفسي.

martynhoyer تم دمج التصحيح الخاص بي ، لذلك عدت إلى الإصدار الأصلي من gatsby-pagination . ما المشكلة التي تواجهها؟

مرحباsgoudie
أنا أستخدم هذا البرنامج التعليمي: https://www.gatsbyjs.org/blog/2017-10-17-building-i18n-with-gatsby/ لكن لا يمكنني العثور على أيٍّ من locales/{lang}/*.json . هل لديك اي برهان؟
2018-04-25 12_04_13-o intermedium agora e banco inter

التكوين الخاص بي:
gasbty-node.js
"" javascriptexports.onPostBuild = () => {
console.log ("نسخ المحلية")
fs.copySync (
path.join (__ dirname، '/ src / locales') ،
path.join (__ dirname، '/ public / locales')
)
}

""

يضيف

exports.onPostBootstrap = () => {
    console.log("Copying locales");
    fs.copySync(
        path.join(__dirname, "/src/locales"),
        path.join(__dirname, "/public/locales")
    );
};

إلى gatsby-node.js

ThiagoMiranda كنت أواجه نفس المشكلة ثم أدركت أن gatsby develop لا يستدعي onPostBuild ، فقط gatsby build يستدعيها. يتم استدعاء onPostBootstrap في كل مرة.

هل يعرف أي شخص كيفية إنشاء https://moz.com/learn/seo/hreflang-tag في التخطيطات؟

RobinHerzog نقوم بإنشائها في قوالب باستخدام Helmet. إنها خاصة بنوع الصفحة ، لذلك على الأقل في حالتنا لم يكن من المنطقي إنشائها في تخطيط.

szimek شكرا على الرد. أنا أفهم ولكن في حالتي سيكون من المثير للاهتمام أن أضعها في التخطيطات.

<link rel="alternate" href={Route['en-us'][this.props.data.prismicDocument.data.group]} hreflang="en-us" /> <link rel="alternate" href={Route['fr-fr'][this.props.data.prismicDocument.data.group]} hreflang="fr-fr" />

في الوقت الحالي ، كما قلت ، انسخ هذه السطور في كل قالب.

لقد بدأت فقط في التطوير باستخدام React / JavaScript ولكن كل ما رأيته لدعم i18n كان معقدًا للغاية. هذا هو عملي الخاص للاستخدام الأكثر شيوعًا: wise-starter

لا تستخدم إعادة التحميل المباشر واللغات الملائمة لتحسين محركات البحث واللغات الافتراضية المفتاح في عنوان url.
يتم إنشاء جميع صفحات .js لجميع اللغات.
يجب إنشاء كل التخطيطات و md. لجميع اللغات لمنع الأخطاء.
مكون LangSelect و Link هما i18n ذكيان.

إذا كنت تستطيع مساعدتي وتشرح لي كيف يمكنني تحسين الكود والأسلوب الخاص بي ، فسأكون ممتنًا.

@ Tom-Pichaud ، أعتقد أنه نظرًا لأنك لا تقوم بتمرير الرسائل إلى مكونات الصفحة ، فلن يتم عرضها بشكل ثابت هناك.

يبدو أن إعداد Markdown i18n في gatsby-node مشابه لما كان يفعله الناس هنا ، لكنني أشعر بالفضول إذا كنت تحصل على عرض ثابت مع تعطيل جافا سكريبت في مكونات صفحتك؟

نعم ، أحصل على عرض ثابت ، كان هذا هو هدفي على أي حال ، i18n-response قم بالخدعة !

TomPichaud هل سيكون من الممكن بالنسبة لك أن تشارك كيف أن رد فعل i18n الذي ذكرته أفضل من js-lingui ؟

شيء واحد لم أحصل عليه تمامًا هو الحاجة الفعلية للحزم الخارجية لتحميل الرسائل المترجمة (ربما بخلاف التعددية والأقارب).

بالنسبة إلى موقع بسيط به محتوى ثابت ، أقوم فقط بتكرار الصفحات لكل لغة onCreatePage وقم بتمرير الإعدادات المحلية إلى context :

// some file with the locales
const locales = {
  en: {
    path: 'en',
    default: true,
  },
  pt: {
    path: 'pt',
  },
}
// gatsby-node.js
exports.onCreatePage = ({ page, boundActionCreators }) => {
  const { createPage, deletePage } = boundActionCreators

  return new Promise(resolve => {
    deletePage(page)

    Object.keys(locales).map(lang => {
      const localizedPath = locales[lang].default
        ? page.path
        : locales[lang].path + page.path

      return createPage({
        ...page,
        path: localizedPath,
        context: {
          locale: lang,
        },
      })
    })

    resolve()
  })
}

بعد ذلك ، في الصفحة الفعلية ، أستخدم الإعدادات المحلية في السياق للاستعلام عن المحتوى باستخدام مرشح الرسم البياني.

لنفترض أن لدي محتوى المنزل بـ /data/home/en.js و /data/home/pt.js :

import React from 'react'

const IndexPage = ({ pathContext: { locale }, ...props }) => {
  const { childHomeJson: data } = props.data.allFile.edges[0].node

  return <div>{data.hello}</div>
}

export const query = graphql`
  query HomeContent($locale: String) {
    allFile(filter: { name: { eq: $locale } }) {
      edges {
        node {
          childHomeJson {
            hello
          }
        }
      }
    }
  }
`

export default IndexPage

يعمل بشكل جيد مع netlifyCMS (وإن كان مطولًا بعض الشيء حتى يدعم i18n) والصور في ملفات JSON (نحتاج إلى إنشاء NodeField جديد بالمسار النسبي حتى يحصل عليه نظام ملفات Gatsby)

ألا يكفي هذا لمعظم الحالات؟

ما زلت أختبر ولم أستخدم أيًا من هذا في الإنتاج ، لكنني أفكر في استخدام واجهة برمجة تطبيقات سياق رد الفعل للإعدادات المحلية لحل بعض المشكلات المعلقة مثل الروابط المترجمة

pbrandone يبدو أن هذا أسلوب رائع بالنسبة لي. أعتقد أنه يجب توثيق شيء مشابه رسميًا.

شكرًا لجميع المدخلات ، فإن كمية الأفكار التي تمت مناقشتها هنا تشير بوضوح إلى الطلب على دعم i18n الموثق جيدًا.

pbrandone هل هذا يعني أنه يجب عليك تحديد جميع المفاتيح التي تستخدمها أي مكونات IndexPage في هذا الاستعلام وتمرير الترجمات إلى جميع المكونات عبر الدعائم؟

أيضًا ، أستخدم قواعد التعددية والتواريخ النسبية ، لذلك يتعين علي تحميل بيانات إضافية خاصة باللغة على أي حال: /

ومع ذلك ، أوافق على أنه سيكون من الرائع أن يكون لديك توثيق رسمي حول كيفية عمل i18n بدون أي مكتبة للحالات البسيطة ثم كيفية القيام بذلك مع المكتبات الأكثر شيوعًا.

szimek حسنا ، في هذه الحالة نعم.

من السهل جدًا إضافة رد فعل intl (أو أي مكتبة i18n أخرى) من أجل:

// in src/components/layout/index.js

import React from 'react'
import { IntlProvider, addLocaleData } from 'react-intl'

// Locale data
import enData from 'react-intl/locale-data/en'
import ptData from 'react-intl/locale-data/pt'

// Messages
import en from '../../data/en.json'
import pt from '../../data/pt.json'

const messages = { en, pt }

addLocaleData([...enData, ...ptData])

const Layout = ({ locale, children }) => (
  <IntlProvider locale={locale} messages={messages[locale]}>
    {children}
  </IntlProvider>
)

export default Layout

ثم على الصفحات:

import React from 'react'
import { FormattedMessage } from 'react-intl'

import Layout from '../components/layouts'

const IndexPage = ({ pathContext: { locale } }) => (
  <Layout locale={locale}>
    <FormattedMessage id="hello" />
  </Layout>
)

export default IndexPage

ولكن بعد ذلك لن تكون قادرًا على استخدام ملفات JSON متعددة (على سبيل المثال لكل صفحة) ، ولا أن يكون لديك جميع بيانات CMS في هذه الملفات للاستعلام والتحويل بقوة الرسم البياني.
باستخدام نهج الرسم البياني ، يمكننا ، على سبيل المثال ، الحصول على بعض المفاتيح مع مسارات للصور في ملفات JSON هذه لتحميل صور مختلفة لكل لغة ولا يزال بإمكاننا استخدام gatsby-image عليها.
ثم أضف netlify CMS لتحرير ملفات JSON هذه 😃

لم تنظر بشكل صحيح إلى الإصدار 2 من gatsby ولكن يبدو أن هناك مكونًا StaticQuery يسمح لنا بالاستعلام عن المكونات الفرعية (يصحح لي أحدهم إذا كنت مخطئًا!)

إذا كان الأمر كذلك ، فيمكننا إنشاء سياق React لجعل اللغة متاحة في أي مكان ثم الاستعلام عن المفاتيح الضرورية في كل مكون باستخدام تصفية الإعدادات المحلية

pbrandone أنت على حق ، إنها تقدم بشكل ثابت بهذه الطريقة. أتذكر اختباره في الماضي وفشلت ، ولكن كان ذلك قبل أن يكون لدي فهم جيد لكيفية عمل gatsby ، ربما كان لدي إعداد react-intl في متصفح gatsby والذي يبدو أنه قد لا يتم عرضه بدون جافا سكريبت. الحل الآن يشبه حلك تمامًا

KyleAMathews أحاول تحديث صفحتنا إلى Gatsby إلى الإصدار 2 ولدينا مشكلة مع استفسارات الإعداد والرسوم البيانية الخاصة بنا على react-intl .

لقد شرحت سابقًا كيف أستخدم التنسيقات الخاصة باللغة لتحميل بيانات اللغة في Gatsby v1 - https://github.com/szimek/gatsby-react-intl-example. في Gatsby v2 كان لدي فكرة لاستبدال هذه التخطيطات بمكونات صفحة خاصة بلغة معينة. كان لدي مكوِّن src/templates/Post.js يعرف اللغة ، ثم مكونات خاصة باللغة مثل src/templates/Post.en.js ، src/templates/Post.de.js لن يؤدي إلا إلى تحميل بيانات اللغة وعرض المكون الحيادي اللغة.

في تعليقك السابق (https://github.com/gatsbyjs/gatsby/issues/3853#issuecomment-367115380) قمت بعرض مثال حيث يحتوي كل مكون صفحة على استعلام لغة محدد.

تكمن المشكلة في أنه عند استدعاء createPage ، أقوم بتمرير أسماء هذه المكونات الخاصة باللغة (على سبيل المثال src/templates/Post.en.js ) كخيار component ، لكن استعلام الرسم البياني موجود في المكون الحيادي اللغة ، لأنه __تماثله تمامًا لجميع اللغات__ (يعتمد على locale ، لكني أقوم بتمريره بـ context ). أود تجنب تكرار نفس الاستعلام بالضبط في جميع هذه المكونات الخاصة باللغة.

هل لديك أي أفكار لحل هذه؟ هل يمكنني استخراج هذا الاستعلام إلى متغير؟ عندما جربته ، اشتكى غاتسبي من أن أسماء الاستعلامات والأجزاء هي نفسها ...

لقد أضفت مؤخرًا بداية Gatsby الافتراضية مع ميزات مسارات URL متعددة اللغات واكتشاف لغة المتصفح. (تجريبي)

برنامج gatsby-starter-default-intl

سمات:

  • التعريب (متعدد اللغات) مقدم من خلال رد فعل دولي .

  • إعادة التوجيه التلقائي بناءً على اللغة المفضلة للمستخدم في المتصفح الذي يوفره المتصفح لانج .

  • دعم مسارات URL متعددة اللغات داخل مكون صفحة واحدة. هذا يعني أنه ليس عليك إنشاء صفحات منفصلة مثل pages/en/index.js أو pages/ko/index.js .

  • استنادًا إلى gatsby-starter-default مع أقل تعديل.

wiziple شكرا! يبدو مثيرًا للاهتمام حقًا. لم يكن لدي أي فكرة أنه يمكنك القيام بشيء مثل هذا: https://github.com/wiziple/gatsby-starter-default-intl/blob/master/src/i18n/withIntl.js#L38؛) آمل أن لا يزال يعمل في Webpack 4 ...

هل من الممكن تحميل البيانات المحلية بنفس الطريقة هنا https://github.com/wiziple/gatsby-starter-default-intl/blob/master/src/i18n/withIntl.js#L6 ؟ نحن ندعم 6 (سبع لغات قريبًا) ، لذا سيكون من الرائع أن أتمكن من تحميل اللغة التي أقوم ببناء الصفحة من أجلها. ليست مشكلة كبيرة إذا لم يكن ذلك ممكنًا - لحسن الحظ ، تكون ملفات البيانات المحلية هذه صغيرة نسبيًا.

سأضطر أيضًا إلى النظر في كيفية إنشاء هذه الصفحات ، لأنه في حالتي لا تتم ترجمة كل صفحة إلى جميع اللغات (لا توجد لغة "مصدر" واحدة) ، وبالتالي لن يعمل الحل باستخدام onCreatePage على الأرجح في حالتي.

آمل أن يحل هذا مشكلتي مع نفس استعلام الرسم البياني في كل مكون صفحة خاص بلغة معينة.

تضمين التغريدة
يحتوي موقع الويب الذي أديره على 14 لغة ويتراوح حجم كل ملف لغة من 12 إلى 15 كيلوبايت. أنا متأكد من أننا بحاجة إلى توفير اللغة الصحيحة لكل موجه لغة في وقت الإنشاء من أجل إنشاء بيانات تحسين محركات البحث. لذلك لست متأكدًا من كيفية التعامل مع هذا دون توفير جميع اللغات.

أفهم أنه يصعب أحيانًا تقديم كل صفحة مترجمة إلى جميع اللغات. قد تتمكن من حل هذا من خلال تقديم بعض الاستثناءات على onCreatePage في gatsby-node.js . في حالتي ، قمت بحلها ببساطة من خلال عدم تقديم لغة مترجمة بغض النظر عن موجه اللغة. 😆 يمكنك العثور على موقع الويب للعرض على الإنتاج من البداية README.md والتحقق من أدائه.

wiziple شكرا جزيلا لك!

لقد استخدمت مكوِّن withIntl مع خدعة require الديناميكية للترجمات (ليس لدي أي فكرة عما إذا كان هناك أي عيوب لاستخدامه) ويبدو أنه يعمل بشكل رائع. لقد حلت المشكلة التي كنت أواجهها - كيفية التعامل مع نفس استعلام الرسم البياني في مكونات صفحات متعددة خاصة باللغة - من خلال وجود مكون صفحة واحد لجميع اللغات.

wiziple شكرا على حصة الريبو. جعلتني على الطريق الصحيح 😄 🎉

يبدو أن lingui هو بديل أفضل . لا أعتقد أن dcroitoru حصل على التقدير المناسب لمثال رائع. يحتاج فقط إلى القليل من الحب لدفعه إلى Gatsby 2.0

أوافق على أن Lingui رائعة حقًا ، على الرغم من أنها لا تزال بحاجة إلى بداية كاملة ، مع أحدث إصدار من Gatsby ولكن أيضًا مع Lingui. المبدئ المذكور غير رسمي ويفقد بعض الميزات في المرة الأخيرة التي راجعتها (على سبيل المثال ، استخدام أداة تحميل لتشغيل ترجمة lingui أثناء التنقل). مؤلف Lingui ل @tricoder42 قال إنه سيقدم الوثائق عندما Lingui V3 هو خارج (والذي يظهر أن يكون قريبا).

ملحوظة: لقد لاحظت أن حاجتي إلى مكتبة i18n انخفضت بعد دمج CMS (DatoCMS) ، لكنني ما زلت بحاجة إلى Lingui لبعض السلاسل التي لا تجد مكانها في CMS وأيضًا للتعددية وربما أشياء أخرى لاحقًا لذلك أنا بالتأكيد تريد الاحتفاظ بها في قاعدة بياناتي.

على أي حال ، في حالتي ، أدى وجود gatsby-plugin-i18n إلى جعل الأشياء مربكة للغاية لأنها غير محفوظة ، ولها اسم محير ، وتلفت الانتباه بعيدًا عن هذه الحلول الرائعة الأخرى مثل js-lingui و CMSes التي أخذتها بعد ذلك بينما يكتشفون ويتجمعون معًا.

لقد صنعت للتو هذا المبدئ لمساعدتك الناس: https://github.com/smakosh/gatsby-starter-i18n
المقال: https://dev.to/smakosh/implement-i18n-to-a-gatsby-site-5ala

لقد قدمت مثالين دوليين مع التكامل بين التفاعل والفاعل

يركز المثال الأول على تجميع الترجمات الحالية فقط في أجزاء js (شيء لم أجده في المكونات الإضافية الأخرى التي راجعتها).

يركز المثال الثاني على استخدام الاستعلامات الديناميكية لتقديم الترجمات المطلوبة فقط لمجموعة الصفحات / اللغة المحددة.

نأمل أن تكون هذه الأمثلة مفيدة لشخص ما.

قام أيضًا بعمل منشور متوسط ​​سريع (ونسيت نشره هنا) مع ما يوجد إلى حد كبير في https://github.com/gatsbyjs/gatsby/issues/3853#issuecomment -395432693 (وإن كان أكثر تعمقًا قليلاً).

https://blog.significa.pt/i18n-with-gatsby-528607b4da81 لأي شخص مهتم

سيتم إغلاق الإصدارات القديمة بعد 30 يومًا من عدم النشاط. ظلت هذه المشكلة هادئة لمدة 20 يومًا ويتم وضع علامة عليها على أنها قديمة. يمكنك الرد هنا أو إضافة التصنيف "ليس قديمًا" للإبقاء على هذه المشكلة مفتوحة!

مرحبًا يا رفاق ، لقد مر عام تقريبًا 😅

لقد قمت مؤخرًا بإصدار ملحق gatsby الجديد gatsby -plugin-intl الذي يجعل موقع gatsby الخاص بك بسهولة كإطار عمل تدويل خارج الصندوق.

العرض التوضيحي: https://gatsby-starter-default-intl.netlify.com

  • إطار تدويل خارج الصندوق مدعوم من react-intl

  • دعم إعادة التوجيه التلقائي بناءً على لغة المستخدم المفضلة في المتصفح

  • دعم مسارات URL متعددة اللغات في مكون صفحة واحدة. هذا يعني أنه ليس عليك إنشاء صفحات منفصلة مثل pages/en/index.js أو pages/ko/index.js .

  • كما اقترح البعض منكم أعلاه ، فهي الآن تجمع اللغة الحالية فقط أثناء وقت الإنشاء.

أيضًا ، أود أن أذكر أن العديد من أمثلة / مبتدئين i18n يتم تقديمها بالفعل من جانب العميل. أفضل طريقة للتحقق مما إذا كان التطبيق يتم عرضه على أنه SSR هو عرض الكود المصدري والتحقق مما إذا كانت النصوص المترجمة موجودة أم لا. يرجى التحقق مرة أخرى من هذا الأمر عندما تقوم بتدويل موقع الويب الخاص بك على gatsby لتحسين محركات البحث.

مرحبًا يا رفاق ، لقد مر عام تقريبًا 😅

لقد قمت مؤخرًا بإصدار ملحق gatsby الجديد gatsby -plugin-intl الذي يجعل موقع gatsby الخاص بك بسهولة كإطار عمل تدويل خارج الصندوق.

العرض التوضيحي: https://gatsby-starter-default-intl.netlify.com

  • إطار تدويل خارج الصندوق مدعوم من react-intl
  • دعم إعادة التوجيه التلقائي بناءً على لغة المستخدم المفضلة في المتصفح
  • دعم مسارات URL متعددة اللغات في مكون صفحة واحدة. هذا يعني أنه ليس عليك إنشاء صفحات منفصلة مثل pages/en/index.js أو pages/ko/index.js .
  • كما اقترح البعض منكم أعلاه ، فهي الآن تجمع اللغة الحالية فقط أثناء وقت الإنشاء.

أيضًا ، أود أن أذكر أن العديد من أمثلة / مبتدئين i18n يتم تقديمها بالفعل من جانب العميل. أفضل طريقة للتحقق مما إذا كان التطبيق يتم عرضه على أنه SSR هو عرض الكود المصدري والتحقق مما إذا كانت النصوص المترجمة موجودة أم لا. يرجى التحقق مرة أخرى من هذا الأمر عندما تقوم بتدويل موقع الويب الخاص بك على gatsby لتحسين محركات البحث.

مرحبًا wiziple ، شكرًا جزيلاً على ذلك ، كنت مجنونة لإيجاد حل لتوطين Gatsby.
ربما لم أفهم الفكرة ، لكن هل لديك كل سلاسل اللغة في ملف واحد فقط؟
هل من الممكن تقسيم JSON لكل لغة إلى المزيد من الملفات ، ربما باستخدام نفس بنية المكونات؟

@ cant89 أرى وجهة نظرك ، لكن هذا غير ممكن حاليًا بدون تغيير رمز المكون الإضافي. أو يمكنك عمل برنامج نصي يوزع دليل src ويأخذ جميع ملفات اللغة المكونة. ادمج في JSON واحد ثم اربطه بـ gatsby develop أو gatsby build .
بمجرد الحصول على جميع ملفات JSON ودمجها ككائن متداخل ، يمكنك أيضًا تحويلها ككائن مسطح.
https://github.com/yahoo/react-intl/wiki/Upgrade-Guide#flatten -messages-object

لدينا مثال جيد لإعداد i18n. https://github.com/gatsbyjs/gatsby/tree/master/examples/using-i18n. ليس لدينا حقًا رأي في أطر عمل i18n. فقط اختر واحدة ترضيك.

لدينا مثال جيد لإعداد i18n. https://github.com/gatsbyjs/gatsby/tree/master/examples/using-i18n. ليس لدينا حقًا رأي في أطر عمل i18n. فقط اختر واحدة ترضيك.

رائع ، شكرًا ، سأحاول!
على أي حال الرابط الموجود في الملف التمهيدي معطل ، ربما تقصد https://using-i18n.netlify.com/ ؟

wardpeet هل يولد المثال الخاص بك سلاسل مترجمة ثابتة (في وقت

monsieurnebo يبدو وكأنه بناء الوقت

@ cant89 ما زلنا نقوم بتحديث نظام أسماء النطاقات ، لذا فقد حان الوقت قريبًا باستخدام-i18n.netlify.com/ هو الرابط الصحيح.

monsieurnebo إنه وقت

لست متأكدًا من أي مكان آخر لطرح هذا السؤال فيه ولكنه مناسب بعض الشيء. هل أي من هذه المكونات الإضافية تدعم gatsby's pathPrefix ؟

i.e. 
// gatsby-config.js

modules.exports = {
    pathPrefix: 'bar'
}

https://foo.com => https://foo.com/bar

but now my language locales will now be https://foo.com/bar/de-DE/
when I think I would prefer it be https://foo.com/de-DE/bar if that makes sense.

حسنًا ، أعتقد أن السابق يكون أكثر منطقية على الرغم من أن pathPrefix هو نوع من جعل مجالك domain.com/prefix لذا قم بتغيير الجذر عند تثبيت Gatsby في دليل فرعي ، إذا لم تقم بتثبيته على دليل فرعي لست بحاجة إليه ، إذا كنت تستخدم دليلًا فرعيًا ، فقم بتغيير البادئة لتكون بعد أن تكسر اللغة ..

الآن السؤال الذي يطرح نفسه ، لماذا تستخدم pathPrefix في المقام الأول؟

المرجع: مستندات pathPrefix

مرحبا،

تدور معظم المناقشات هنا حول كيفية إنشاء موقع i18n على موقع gatsby. ولكن هناك فرق بين تشغيل POC ووجود نظام جاهز للإنتاج محسن.

إذا كنت مهتمًا بقراءة المزيد حول تقسيم الكود وملفات i18n ، ولماذا لم يتم تحسين معظم الحلول في هذا الموضوع ، فستجد هذه المشكلة مفيدة

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات

القضايا ذات الصلة

theduke picture theduke  ·  3تعليقات

andykais picture andykais  ·  3تعليقات

dustinhorton picture dustinhorton  ·  3تعليقات

totsteps picture totsteps  ·  3تعليقات

Oppenheimer1 picture Oppenheimer1  ·  3تعليقات