2

How do I configure CFWheels to display the following XML at http://mydomain.com/sitemap.xml?

<?xml version="1.0" encoding="UTF-8"?>
<urlset
      xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
            http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">

      <-- I'll add the <url> tags dynamically here later -->
</urlset>

I've removed the "sitemap.xml" from the web.config file.

After this I'm not sure what to do about creating the controller and view. Should I create a "sitemap.xml" folder in the "views" folder, then add an "index.cfm" file and then add the XML above?

Should I create a "sitemap.xml.cfc" file in the "controllers" folder? And what should the controller file contain?

Should it look something like this?

<cfcomponent extends="Controller" output="false">
<cfscript>  
  function init(){
    // Let CFWheels know what type of output this controller can 'provide'
    provides("xml");
  }

  function index(){

  }
</cfscript>
</cfcomponent>

Do I need to add an entry to the routes.cfm?

Micah
  • 1,221
  • 17
  • 42

2 Answers2

2

Setting up the Controller

Your controller's index() method should look something like this. It's stored at controllers/Sitemap.cfc.

function init() {
    // Grab data about URLs from model or build an array of structs to pass to the view
    urls = model("page").findAll(); // This line is just an example

    // Call `renderWith()` to instruct Wheels that this requires a special content-type
    renderWith(urls);
}

Setting up the View

Your view at views/sitemap/index.xml.cfm can then generate the required XML:

<cfoutput>

<?xml version="1.0" encoding="UTF-8"?>
<urlset
    xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
        http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">

    #includePartial(partial="url.xml", query=urls)#
</urlset>

</cfoutput>

Then you can implement a partial at views/sitemap/_url.xml.cfm representing a single item in your query or array. Let me know if you're using something other than a query, and I can modify my example above.

<cfoutput>

<url>
    <loc>#arguments.uri#</loc>
    <loc>#arguments.updatedAt#</loc>
</url>

</cfoutput>

Keep in mind that when you use a partial like this, query columns or struct keys get placed into the arguments scope, which is why I'm referencing arguments.uri and arguments.updatedAt in my fictitious example.

Accessing via URL

Depending on your server's URL rewriting capabilities, you may need to try a couple things to get the URL to do what you want.

You may be able to do something like this in config/routes.cfm (but I've only tested this on Apache):

<cfset addRoute(pattern="sitemap.[format]", controller="sitemap", action="index")>
<cfset addRoute(pattern="sitemap", controller="sitemap", action="index")>

Then you can load the URL at http://www.example.com/sitemap.xml

If that doesn't work, try this:

<cfset addRoute(pattern="sitemap.xml", controller="sitemap", action="index")>
<cfset addRoute(pattern="sitemap", controller="sitemap", action="index")>

Again, you can load the URL at http://www.example.com/sitemap.xml

Finally, if that doesn't work, remove the extra lines from config/routes.cfm and load this URL (which most definitely will always work regardless):

`http://www.example.com/sitemap?format=xml`.
Chris Peters
  • 17,918
  • 6
  • 49
  • 65
  • Thanks for the in-depth examples. Unfortunately, the routes aren't working for `http://www.example.com/sitemap.xml` either. `http://www.example.com/sitemap/` works but `http://www.example.com/sitemap.xml` ends up triggering the onmissingtemplate.cfm and displays a "File Not Found!" message. – Micah Feb 01 '12 at 19:54
  • You may want to compare `web.config` and `.htaccess` in the GitHub repo and see if you can finesse `web.config` to work better with dots in the path. https://github.com/cfwheels/cfwheels/blob/new-master/web.config https://github.com/cfwheels/cfwheels/blob/new-master/.htaccess – Chris Peters Feb 01 '12 at 20:23
  • 1
    Can you see if this patch works? Looks like something got broken in the CFML in Wheels 1.1.7. https://github.com/cfwheels/cfwheels/commit/aa04eb927daa429a3bdc3a4d4e1d221c823e63b3 – Chris Peters Feb 05 '12 at 15:40
  • I see you accepted my answer. Did the patch in my above comment work? – Chris Peters Feb 06 '12 at 23:29
  • Yes, Thanks! Using `sitemap.[format]` with the [patch](https://github.com/cfwheels/cfwheels/commit/aa04eb927daa429a3bdc3a4d4e1d221c823e63b3) does work. I should mention that there is another option for those who don't wish to apply this patch which is described [here](http://stackoverflow.com/a/9112039/675590). – Micah Feb 06 '12 at 23:48
1

First, you will have to have configured your webserver to do full URL Rewriting, if you haven't already. That way you won't have to have index.cfm in your URL (http://mydomain.com/index.cfm/foo/bar becomes http://mydomain.com/foo/bar).

Once that is in place, modify your config/routes.cfm like so:

<cfset addRoute(name="sitemap",
        pattern="/sitemap.xml",
        controller="sitemap",
        action="list") />

Then you can add your XML code here:

/views/sitemap/list.cfm

and, optionally a controller here:

/controllers/Sitemap.cfc (with a function named list)

edit

Since the above isn't working quite right, I took a look at the stock rewrite rules that come with CFWheels, and noticed a big problem:

RewriteCond %{REQUEST_URI} !^.*/(flex2gateway|jrunscripts|cfide|cfformgateway|cffileservlet|railo-context|files|images|javascripts|miscellaneous|stylesheets|robots.txt|sitemap.xml|rewrite.cfm|favicon.ico)($|/.*$) [NC]

Note the "sitemap.xml". Remove this from your list, leaving you with this:

RewriteCond %{REQUEST_URI} !^.*/(flex2gateway|jrunscripts|cfide|cfformgateway|cffileservlet|railo-context|files|images|javascripts|miscellaneous|stylesheets|robots.txt|rewrite.cfm|favicon.ico)($|/.*$) [NC]

You may have to restart/reload your web server. But that should do it.

edit

One last idea - you could add a rewrite rule in your webserver that redirects requests for /sitemap.xml to /sitemap, since you know that one works.

Jake Feasel
  • 16,785
  • 5
  • 53
  • 66
  • This isn't working when addressing http://domain.com/sitemap.xml. It does work for http://domain.com/sitemap/. To remove the layout, I added `renderWith(data="#urls#", layout="false");` to the `list()` function of in the controller. – Micah Feb 01 '12 at 19:48
  • Removing "sitemap.xml" from the rewrite pattern was the first thing I did. In my case I removed it from the web.config file as I'm using the IIS rewrite module. Any other ideas? – Micah Feb 01 '12 at 20:12
  • Thanks for you help Jake. Your suggestion to modify the rewrite does work with some modifications which you can get a gist for [here](http://stackoverflow.com/a/9112039/675590) – Micah Feb 06 '12 at 23:54