druj_nasu
druj_nasu

Reputation: 171

Getting the current language from editor(not frontend), but from component view tsx(Polylang and Sage)

I’m wondering if someone had to do this before. I implemented a solution that works but I am wondering if there is a clean way to do it. So I have a component(.tsx) that list articles using the wordpress API, to fill out a Checkbox with articles titles, but because there are 2 languages for backend and frontend, when the user is writing a page or introducing the content, I need to filter the article list per current language, so I need to know in which language is editing the page.

So I did a reasearch a I tried a couple of things, but what it worked for me. Was… that I realized that … in the DOM from the page, polyland is always setting a language css class to the body, which actually have the current language from the editor, so I did a function to read this and I assigned the current language to the articles to display. However …in a future where for some reason they decided to change the name of the class, or something like, this might not work anymore. Do you have any idea? There is something maybe native, that can be better to use…

Here an example of what I did, that works but I would like to improve

import { useState, useEffect } from "react";
import { __ } from "@wordpress/i18n";
import { useBlockProps } from "@wordpress/block-editor";
import {
  fetchArticleData,
  fetchArticlesList,
  hasLangClass,
} from "scripts/components/article";

export const name = `test/articleslider`;

export const title = __("Article-Slider", "radicle");

export const category = `test`;

export const icon = `slides`;

export const apiVersion = 2;

export const attributes = {
  headline: {
    type: `string`,
    default: __(``, `radicle`),
  },
  topline: {
    type: `string`,
    default: __(``, `radicle`),
  },
  articleIds: {
    type: "array",
    default: [],
  },
  articlesData: {
    type: "object",
    default: {},
  },
  showBackground: {
    type: 'boolean',
    default: 'false',
  },
};

export const edit = ({ attributes, setAttributes }) => {
  const props = useBlockProps({
    className: `border rounded-md p-3`,
    attributes,
  });

  const { headline, topline, articleIds, articlesData, showBackground } = attributes;

  const [articlesList, setArticlesList] = useState([]);
  const [isLoading, setIsLoading] = useState(true);
  const [currentLanguage, setCurrentLanguage] = useState("");
  const [searchTerm, setSearchTerm] = useState('');


  useEffect(() => {
    hasLangClass("pll-lang-en")
      ? setCurrentLanguage("en")
      : setCurrentLanguage("de");
  }, []);

  useEffect(() => {
    populateSelect();
  }, [currentLanguage]);

  useEffect(() => {
    getArticles(attributes.articleIds);
  }, [attributes.articleIds, currentLanguage]);

  const populateSelect = async () => {
    if (currentLanguage) {
      const selectOptions = await fetchArticlesList(currentLanguage);
      setArticlesList(selectOptions);
      setIsLoading(false);
    }
  };

  const getArticles = async (articleIds) => {
    setAttributes({ articlesData: {} });
    const articlesData = await fetchArticleData(articleIds, currentLanguage);
    setAttributes({ articlesData });
  };

  const handleArticleChange = async (isChecked, articleId) => {
    let updatedArticleIds;
    if (isChecked) {
      updatedArticleIds = [...articleIds, articleId];
    } else {
      updatedArticleIds = articleIds.filter((id) => id !== articleId);
    }
    setAttributes({ articleIds: updatedArticleIds });
    const articlesData = await fetchArticleData(updatedArticleIds, currentLanguage);
    setAttributes({ articlesData });
    setSearchTerm('');
  };

  const handleSearchTermChange = (event) => {
    setSearchTerm(event.target.value);
  };

  const filteredArticlesList = articlesList.filter((article) =>
    article.label.toLowerCase().includes(searchTerm.toLowerCase())
  );

  const handleUnselectAll = () => {
    setAttributes({ articleIds: [] });
    setSearchTerm('');
  };


  return (
    <div {...props}>
    //Control view code
    </div>
  );
};

export const save = () => null;


What hasClass does:

export const hasLangClass = (className: string): boolean => {
  const bodyElement = document.body;

  return bodyElement.classList.contains(className);
};

Thank you in advance for your help and advice

Upvotes: 0

Views: 70

Answers (0)

Related Questions