【问题标题】:Porting nl2br to Javascript/React - How to manually escape text?将 nl2br 移植到 Javascript/React - 如何手动转义文本?
【发布时间】:2019-10-31 04:04:22
【问题描述】:

我正在将一个小型项目从 Flask + 服务器端模板渲染移植到 Flask + React。一个组件使用a Jinja2 custom filter, nl2br, 只需将纯文本中的换行符转换为 HTML 中的 <p><br> 标记。我想在惯用的 Javascript 中实现类似的东西(重点是 React)。

我认为我缺少的关键步骤是一种手动执行与 React 应用于 JSX 中的字符串变量相同的转义的方法。有没有暴露在哪里?

原始 Python 代码:

import re
from jinja2 import evalcontextfilter
from markupsafe import Markup, escape

_paragraph_re = re.compile(r'(?:\r\n|\r|\n){2,}')

@evalcontextfilter
def nl2br(eval_ctx, value):
    result = u'\n\n'.join(u'<p>%s</p>' % p.replace('\n', Markup('<br>\n'))
                          for p in _paragraph_re.split(escape(value)))
    if eval_ctx.autoescape:
        result = Markup(result)
    return result

代码大纲:1. 转义输入,2. 根据换行符对将其拆分为段落 (&lt;p&gt;),3. 用 &lt;br&gt; 标签替换段落内的换行符,以及 4. 用 @987654327 换行@ 如果配置需要 HTML 输出并使用 @evalcontextfilter 装饰器来禁用不需要的自动转义。

中间两步可以直接翻译成Javascript(只是正则表达式和字符串处理)。我认为最后一步的 React 类似物是使用 dangerouslySetInnerHTML。但我想不出一个好的方法来执行第一个。 NPM 上有各种各样的 HTML 转义库,但如果可能的话,我想使用 React 的内置转义来保持一致性。

【问题讨论】:

    标签: javascript python reactjs escaping jinja2


    【解决方案1】:

    这可以在 React 中以稍微不同的方式实现,只需在构建 DOM 树后转义单个字符串,而不是像 Python 代码中那样在拆分之前转义所有内容:

    const _p_re = /((?:\r\n|\n){2,})/;
    const _br_re = /(\r\n|\r|\n)/;
    
    function nl2br(text) {
      if (text === "") return <p />;
      let ps = text.split(_p_re);
      for (let i = 0; i < ps.length; i += 2) {
        const p = ps[i];
        let parts = p.split(_br_re);
        for (let j = 0; j < parts.length; j += 2) {
          parts[j] = <React.Fragment key={j}>{parts[j]}</React.Fragment>
        }
        for (let j = 1; j < parts.length; j += 2) {
          parts[j] = (
            <React.Fragment key={j}>
              <br />
              {parts[j]}
            </React.Fragment>
          );
        }
        ps[i] = <p key={i}>{parts}</p>;
      }
      return <>{ps}</>;
    }
    

    注意:我认为这段代码没有正确使用 key 属性,因为我目前还不太明白。但它适用于我的目的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-15
      • 2018-08-30
      • 2012-09-25
      • 2014-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多