Re: Rule based on custom keyword set

Splash Forums Rewrite Users Rule based on custom keyword set Re: Rule based on custom keyword set

#22944

Absolutely!

Check this out – you have several approaches to choose from:

The first is an example that will match all possible category combinations, forward the inbound URLs to the given destination, and also rewrite outbound URLs to match the pattern (using parameter names to determine which URLs to generate from the outbound links).

public class DynamicConstrainedConfiguration extends HttpConfigurationProvider
{
@Override
public Configuration getConfiguration(final ServletContext context)
{
ConfigurationBuilder config = ConfigurationBuilder.begin();

config.addRule(Join.path("/{1}/{2}").to("/CategorySearch.xhtml"));

return config;
}

@Override
public int priority()
{
return 0;
}
}

That’s it, you’re done – Just make sure that when you generate your outbound links, you use the Query-parameters with the same names as “1” and “2” – e.g:

<h:link outcome="/CategorySearch.xhtml">
<f:param name="1" value="car" />
<f:param name="2" value="tires" />
</h:link>

The second is an example of using Constraints to limit the valid URLs for a given Path. These categories could be loaded from a database, or from a CDI or Spring bean if you are using the integration modules. This will ensure that you have more valid information from the client.

public class DynamicConstrainedConfiguration extends HttpConfigurationProvider
{
@Override
public Configuration getConfiguration(final ServletContext context)
{
ConfigurationBuilder config = ConfigurationBuilder.begin();

config.addRule(Join.path("/{1}/{2}").to("/CategorySearch.xhtml")
.where("1").constrainedBy(categoryConstraint)
.where("2").constrainedBy(subCategoryConstraint)
);

return config;
}

private Constraint<String> categoryConstraint = new Constraint<String>() {
@Override
public boolean isSatisfiedBy(Rewrite event, EvaluationContext context, String value)
{
return Arrays.asList("car", "anime", "garden", "diy").contains(value);
}
};

private Constraint<String> subCategoryConstraint = new Constraint<String>() {
@Override
public boolean isSatisfiedBy(Rewrite event, EvaluationContext context, String value)
{
return Arrays.asList("engine", "tires", "hikaru", "bycicle-repair").contains(value);
}
};

@Override
public int priority()
{
return 0;
}
}

Or you can define each URL directly, however, this is less recommended because you don’t benefit from outbound URL-rewriting (the client-facing URLs in your HTML will still be /CategorySearch.xhtml and the links will not retain contextual information such as which category the user is viewing. You will need to set up these rules yourself.

public class LiteralConfiguration extends HttpConfigurationProvider
{
@Override
public Configuration getConfiguration(final ServletContext context)
{
ConfigurationBuilder config = ConfigurationBuilder.begin();

Set<String> categories = new HashSet<String>(Arrays.asList("/car/engine","/car/tyres","/anime/hikaru"));

for (String c : categories) {
config.addRule()
.when(Direction.isInbound().and(Path.matches(c)))
.perform(Forward.to("/CategorySearch.xhtml"));

config.addRule()
.when(Direction.isOutbound().and(Path.matches("/CategorySearch.xhtml"))))
.perform(Forward.to("/CategorySearch.xhtml"));

// Note that we have not bound any values of the initial request URL to a request parameter
// so you will need to do that as well. This is not a recommended approach unless you are
// extremely fluent in URL-rewriting techniques.
}

return config;
}

@Override
public int priority()
{
return 0;
}
}

My recommendation would be to use the first approach – it is by far the simplest, and if you need to, you can add constraints or additional Conditions to the rule in order to get more precise behavior.

I hope this is helpful,

~Lincoln