博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用 Chinese_pinyin + Friendly_id 为中文标题生成 Slug
阅读量:6346 次
发布时间:2019-06-22

本文共 1744 字,大约阅读时间需要 5 分钟。

在许多项目中,我们可能都会遇到需要为数据生成 slug 的场景,这些场景类似于:

  • 基于商品名称生成 slug

  • 基于文章标题生成 slug

至于为什么需要生成 slug,而不是使用比如 Rails 中默认自增的主键也就是数据的 id,原因其实很简单:

  • 使用自增 id 容易暴露数据,比如通过订单 id 可能导致遍历所有订单,不信,你看这里就有个

  • 增加 URL 友好性,/products/18376 这样的链接肯定没有比 /products/apple-watch-gold 这样的链接更招人喜欢

friendly_id 是用来生成 slug 的 ruby gem,假设我们有一个产品模型 Product,使用 friendly_id 为商品名称(name)生成 slug 的示例代码如下:

class Product < ActiveRecord::Base  friendly_id :name, use: :sluggedend

上面的代码理论上来说已经完成我们所需要的工作了,但是如果 title 包含中文的话,生成的 slug 就有点类似 30f175f4-1e56-4e3a-823d-a7c1a5d32b29 这样的乱码了,实际上这个 slug 对应的原来的 title 是 测试产品。这样的 slug 虽然避免了自增 id 的弊端,但是却丧失了友好性。如果 slug 能够基于汉语拼音生成,岂不更好?

自己控制 slug 生成方式

阅读 可以找到以下代码:

module FriendlyId  module Slugged    # ...    def normalize_friendly_id(value)      value.to_s.parameterize    end    # ...  endend

这段代码便是 friendly_id 基于输入生成 slug 的核心代码,使用 ActiveSupport 扩展后的 String 类的 方法,此方法会将除了英文字母、数字、短横线以及下划线之外的字符转换为 -,所以不适用于中文的情况,我们需要,以满足我们的需求。

中文拼音利器——

中文生成中文拼音的工具,我选择了黄志敏先生写的 chinese_pinyin 这个 gem,推荐理由就是简单够用。

以下是单独使用这个 gem 时的示例:

2.2.0 :009 > Pinyin.t("中国人") => "zhong guo ren"2.2.0 :010 > Pinyin.t("Hello, 李雷") => "Hello  li lei"

组装!!!

根据 ,如果你只需要为单独一个 model 定制 slug 的生成逻辑,那么建议你只在相关的 model 中定义同名方法即可。但是由于我是需要为多个 model 定制中文的 slug 生成逻辑,所以我选择了直接重定义 FriendlyId::Slugged 模块中的这个方法:

# config/initializers/friendly_id/slugged.rbmodule FriendlyId  module Slugged    # 重定义 friendly_id 方法,实现 slug 从中文到拼音,非中文不受影响    def normalize_friendly_id(value)      Pinyin.t(value.to_s).parameterize    end  endend

这样的定义方式使得新的 normalize_friendly_id 方法对所有依赖 friendly_id 的代码都生效。

最后通过新的方法为我们的产品生成新的 slug,现在“测试产品”得到的 slug 变为 ce-shi-chan-pin 了:

product.update(slug: nil)  # 显式清空 slug, friendly_id 在 save 时会自动重新生成 slug

最后产品的链接已变为 /products/ce-shi-chan-pin,比起 /products/30f175f4-1e56-4e3a-823d-a7c1a5d32b29,可真是叫人心旷神怡。

转载地址:http://lbjla.baihongyu.com/

你可能感兴趣的文章
Linux定义系统提示符的变量:PS1
查看>>
udp_client.c udp_server.c
查看>>
数据存储及说明
查看>>
SCI杂志分区规则
查看>>
轻触开关内部结构
查看>>
netty-socketio使用namespace
查看>>
Java计算日期和时间差
查看>>
Android 自定义ScrollView(具有反弹效果的ScrollView,能够兼容横向的滑动)
查看>>
ASP.NET MVC+EF框架+EasyUI实现权限管理系列(8)-DbSession线程内唯一
查看>>
开机黑屏 仅仅显示鼠标 电脑黑屏 仅仅有鼠标 移动 [已成功解决]
查看>>
分享一段H264视频和AAC音频的RTP封包代码
查看>>
GUI程序设计
查看>>
browser.html – HTML 实现 Firefox UI
查看>>
github入门教程:第一步
查看>>
服务器负载监控
查看>>
JS滚轮事件(mousewheel/DOMMouseScroll)了解
查看>>
Java从零开始学十六(多态)
查看>>
多线程之线程池Executor应用
查看>>
AngularJS中的$http.post与jQuery.post的区别
查看>>
灯光探测器LightProbe[Unity]
查看>>