Adam Radivojevic
Adam Radivojevic

Reputation: 93

How to replace multiple strings in html in order to wrap items in a jsx component?

I have WordPress content for my blog, which looks like this:

<ul>
<li>Bla 1</li>
<li>Bla 2</li>
<li>Bla 3</li>
<li>Bla 4</li>
<li>Bla 5</li>
<li>Bla 6</li>
</ul>

I need to replace <ul> and </ul> with a React opening and closing component tags so that I could display a "show more" (react-show-more-text node package) button after a couple of list items.

I tried doing that using react-string-replace node package, however it can perform only one regex operation per line, and I can't return a non closed JSX component: First regex line would be to replace <ul> with , to end up with:

 <ShowMoreText>     
    <li>Bla 1</li>
    <li>Bla 2</li>
    <li>Bla 3</li>
    <li>Bla 4</li>
    <li>Bla 5</li>
    <li>Bla 6</li>
    </ul>

However, I can't do a second regex because I can't return a non-complete JSX code - I need to include a closing tag for .

Is there any way to return a non-complete JSX code and then complete it on the second regex run? Or am I doing this completely wrong and If so - what would be the best way to do this?

Edit: WordPress content doesn't always begin with <ul>, so it would be best if the solution included a way to process an entire blog post, and return with <ul> replaced with <ShowMoreText>, and </ul> with </ShowMoreText>

Upvotes: 1

Views: 655

Answers (1)

lissettdm
lissettdm

Reputation: 13078

You can use html-react-parser to convert the html string to JXS elements. Use the replace function to replace the UL nodes for other elements and domToReact to render it's children:

import parse, { domToReact } from "html-react-parser";

const text = `<div><ul>
                  <li>Bla 1</li>
                  <li>Bla 2</li>
                  <li>Bla 3</li>
                  <li>Bla 4</li>
                  <li>Bla 5</li>
                  <li>Bla 6</li>
                </ul></div>`;

  const render = () => {
    return parse(text, {
      replace: ({ tagName, children }) => {
        if (tagName === "ul") {
          return <ShowMoreText>{domToReact(children)}</ShowMoreText>;
        }
      }
    });
  };
  return (
    <div>
      <h1>Hello StackBlitz!</h1>
      <p>Start editing to see some magic happen :)</p>
      {render()}
    </div>
  );
}

Working example

Upvotes: 2

Related Questions