Creating permalinks with Grails

| Comments

I’ve been working with Grails for some time now and if I had to choose just one good thing to say about it is how it’s community is really great!

I think it’s time to start giving back some contribution, and here’s the first one: A Permalink Codec to generate permalinks based on strings. It strips out all non word chars and convert the resulting string to lowercase:

/*
 * Copyright 2010 Deluan Cotts (grails@deluan.com.br)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.deluan.grails.codecs

import java.util.regex.Matcher
import java.util.regex.Pattern

/**
 * Strip all non word chars, convert to lowercase
 */
class PermalinkCodec {
    private static final String[] CARACTERES_SEM_ACENTO
    private static final Pattern[] PATTERNS

    static {
        CARACTERES_SEM_ACENTO = ["a", "e", "i", "o", "u", "c", "n"]
        PATTERNS = new Pattern[CARACTERES_SEM_ACENTO.length]
        PATTERNS[0] = Pattern.compile("[áàãâä]", Pattern.CASE_INSENSITIVE)
        PATTERNS[1] = Pattern.compile("[éèêë]", Pattern.CASE_INSENSITIVE)
        PATTERNS[2] = Pattern.compile("[íìïî]", Pattern.CASE_INSENSITIVE)
        PATTERNS[3] = Pattern.compile("[óòöõô]", Pattern.CASE_INSENSITIVE)
        PATTERNS[4] = Pattern.compile("[úùüû]", Pattern.CASE_INSENSITIVE)
        PATTERNS[5] = Pattern.compile("ç", Pattern.CASE_INSENSITIVE)
        PATTERNS[6] = Pattern.compile("ñ", Pattern.CASE_INSENSITIVE)
    }

    private static String replaceSpecial(String text) {
        String result = text
        for (int i = 0; i < PATTERNS.length; i++) {
            Matcher matcher = PATTERNS[i].matcher(result)
            result = matcher.replaceAll(CARACTERES_SEM_ACENTO[i])
        }
        return result
    }

    static encode = {str ->
        str = replaceSpecial(str.toString().toLowerCase())
        return str.replaceAll("\\W", "-")
    }

}

To use it in your Grails project, save it in grails-app/utils/com/deluan/grails/codecs folder as PermalinkCodec.groovy.

Please read the (excelent) Grails manual for more info on how to use codecs.

Comments