Home > Software design >  How to reduce repetition in jQuery function for appending URLs to language toggle menu
How to reduce repetition in jQuery function for appending URLs to language toggle menu

Time:10-06

I'm setting up a multi-language dropdown toggle without server side access. It's for a WordPress site with Twig integrated, so the usual WP niceties for handling things like getting the home and path URLs are not available. With those limitations, jQuery seems to be the most workable solution.

Here's what I have so far - this updates the href attributes in a dropdown menu for toggling between four sites: English (default, blog ID:1), German, French, and Spanish. The script below works well, but I'd like to reduce the repetition if I can. Putting the .indexOf items in an array duplicates the 2-letter country string in the URL, which is why the code is in this super repetitive state.

Ideally I'd like to have an if statement that checks for /de, /fr, and /es since those three blocks are nearly identical. Thanks in advance for any pointers.

  var langDropPathname = window.location.pathname.slice(3); // cut 2-letter country and slash from path for non-default sites
  var langDropPathEN = window.location.pathname; // path for default site
  var langDropDE = "/de";
  var langDropFR = "/fr";
  var langDropES = "/es";

  if (window.location.href.indexOf("/de/") > -1) {
    $(".langDropEN").attr('href', langDropPathname);
    $(".langDropDE").attr('href', langDropDE langDropPathname);
    $(".langDropFR").attr('href', langDropFR langDropPathname);
    $(".langDropES").attr('href', langDropES langDropPathname);

    if ($("body").hasClass("error404")) {
      document.location.href=langDropDE;
    }

  } else if (window.location.href.indexOf("/fr/") > -1) {
    $(".langDropEN").attr('href', langDropPathname);
    $(".langDropDE").attr('href', langDropDE langDropPathname);
    $(".langDropFR").attr('href', langDropFR langDropPathname);
    $(".langDropES").attr('href', langDropES langDropPathname);

    if ($("body").hasClass("error404")) {
      document.location.href=langDropFR;
    }

  } else if (window.location.href.indexOf("/es/") > -1) {
    $(".langDropEN").attr('href', langDropPathname);
    $(".langDropDE").attr('href', langDropDE langDropPathname);
    $(".langDropFR").attr('href', langDropFR langDropPathname);
    $(".langDropES").attr('href', langDropES langDropPathname);

    if ($("body").hasClass("error404")) {
      document.location.href=langDropES;
    }

  } else {
    $(".langDropEN").attr('href', langDropPathEN);
    $(".langDropDE").attr('href', langDropDE langDropPathEN);
    $(".langDropFR").attr('href', langDropFR langDropPathEN);
    $(".langDropES").attr('href', langDropES langDropPathEN);
  }

CodePudding user response:

Simply iterating over an array of ['/de', '/fr', '/es'] looks like it'd do the trick.

const langs = ['/de', '/fr', '/es'];
const lang = langs.find(substr => window.location.href.includes(substr));
const suffix = lang ? langDropPathname : langDropPathEN;
$(".langDropEN").attr('href', suffix);
$(".langDropDE").attr('href', langDropDE   suffix);
$(".langDropFR").attr('href', langDropFR   suffix);
$(".langDropES").attr('href', langDropES   suffix);

if ($("body").hasClass("error404") && lang) {
    document.location.href = lang.slice(1);
}

I don't know the broader context of the code, but it'd be even better if you could put all of the languages together, instead of singling out a few specific ones. Perhaps something like

const langs = {
  de: <content of langDropDE>
  fr: <content of langDropFR>
  ...
}

for all languages, then

const langEntry = Object.entries(langs)
  .find(entry => window.location.href.includes('/'   entry[0]));

and proceed from there, now that you have the matching language string and associaed langDrop in the found entry.

CodePudding user response:

you can match with a regular Expression

const
  langDropPathEN   = window.location.pathname // path for default site
, langDropPathname = langDropPathEN.slice(3) // cut 2-letter country and slash from path for non-default sites
, LangDrop         = { DE: '/de', FR: '/fr', ES: '/es' }
, LangRegEx        = new RegExp('/de/|/fr/|/es/')  
  ;

let lang = window.location.href.match(LangRegEx)

if (!!lang)
  {
  $(".langDropEN").attr('href', langDropPathname);
  $(".langDropDE").attr('href', langDrop.DE  langDropPathname);
  $(".langDropFR").attr('href', langDrop.FR  langDropPathname);
  $(".langDropES").attr('href', langDrop.ES  langDropPathname);

  if ($("body").hasClass("error404")) 
    document.location.href = lang[0].slice(0,3);
  }
else
  {
  $(".langDropEN").attr('href', langDropPathEN);
  $(".langDropDE").attr('href', langDrop.DE  langDropPathEN);
  $(".langDropFR").attr('href', langDrop.FR  langDropPathEN);
  $(".langDropES").attr('href', langDrop.ES  langDropPathEN);
  }
  • Related