How do I render pages with “file” extensions like xml, json, csv, etc. in CFWheels with the file type in the URL?

StackOverflow https://stackoverflow.com/questions/9105375

Question

I can't seem to figure out how to create pages in CFWheels with clean URLs that contain "file" extensions.

I'd like to be able to do the following:

As apposed to this:

I've read through these docs but am still unclear about the actual implementation.

Lets say I have a controller (/controllers/Product.cfc) that looks something like the following:

<cfcomponent extends="Controller">

    <cffunction name="init">
        <cfset provides("html,json,xml")>
    </cffunction>

    <cffunction name="index">
        <cfset products = model("product").findAll(order="title")>
        <cfset renderWith(products)>
    </cffunction>

</cfcomponent>

How do I implement the view? Should it be views/products/index.xml.cfm?

<?xml version="1.0" encoding="UTF-8"?>
<products>
    <product><!-- product data goes here --></product>
</products>

How do I implement the routes.cfm?

I should note that I'm also using the default web.config and have <cfset set(URLRewriting="On")> in the config/setting.cfm.

Was it helpful?

Solution

Assumption about routes is correct. But you have to make sure rewriting works properly, say not partially. You can access urls like /controller/action, right? Not /rewrite.cfm/controller/action.

So route definition can look like this:

<cfset addRoute(name="indexProducts", pattern="products.[format]", controller="product", action="index") />

In the index method you'll have params.format populated with actual value, wich you want to validate (ListFind should work).

View template for this page should have the name of its action: /views/product/index.cfm. Nothing special needed here unless you want to load views conditionally, for example separate view for each format. In this case you want to check out renderPage function. It can be used to override the default view.

UPDATE

OK, I've tested this solution and it wont work. Routes do not support anything except slashes as delimiter. So this kind of route can work only this way:

<cfset addRoute(name="indexProducts", pattern="products/[format]", controller="product", action="index") />

I guess we don't want to modify CFWheels code (which is bad idea without further pull request any way), so I would recommend using web-server rewriting. For example, in Apache it may look like this:

RewriteRule ^products\.(xml|json|html)$ product/index?format=$1 [NS,L]

You are using IIS, so it should look similar to this (NOT TESTED):

<rule name="Products listing" enabled="true">
    <match url="^products\.(xml|json|html)$" ignoreCase="true" />
    <action type="Rewrite" url="product/index?format={R:1}" />
</rule>

Think it's better approach than trying to create controllers named like ProductsXml, ProductsJson etc.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top