Removing index.cfm From Mura CMS URLs on Windows/IIS7

If you have an installation of Mura CMS on Windows running IIS7+ and you're looking to remove "index.cfm" from the URL for search engine optimization (SEO) or any other reason, then here's a pretty simple and painless method to do just that.

First, IIS7 does not have their URL Rewrite Module installed by default. So you'll need to download and install URL Rewrite Module 2.0 for your server (x86 / x64).

After that's done, your next decision is to choose whether or not you wish to have the SiteID display in the URL. Some users prefer to have that, and some don't depending on their particular usage of Mura.

Option 1: Allow For Missing SiteID AND index.cfm From The URL

Create a "web.config" file with the following code and place it at the root of your Mura installation:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="Mura CMS Rewrite Option 1" enabled="true">
                    <match url="^([a-zA-Z0-9/-]+)$" ignoreCase="false" />
                    <conditions logicalGrouping="MatchAll">
                        <add input="{DOCUMENT_ROOT}{URL}" matchType="IsDirectory" ignoreCase="false" negate="true" />
                    </conditions>
                    <action type="Rewrite" url="/index.cfm{URL}" />
                </rule>
            </rules>
        </rewrite>
        <defaultDocument>
            <files>
                <remove value="index.cfm" />
                <add value="index.cfm" />
            </files>
        </defaultDocument>
    </system.webServer>
</configuration>

Then, update your settings.ini.cfm file with the following settings and from the Admin > Reload Application:

siteidinurls=0
indexfileinurls=0

Option 2: Allow For Missing index.cfm From The URL, But Keep SiteID

Create a "web.config" file with the following code and place it at the root of your Mura installation:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="Mura CMS Rewrite Option 2" enabled="true">
                    <match url="^([a-zA-Z0-9-]{1,})/([a-zA-Z0-9/-]+)$" ignoreCase="false" />
                    <conditions logicalGrouping="MatchAll">
                        <add input="{DOCUMENT_ROOT}{URL}" matchType="IsDirectory" ignoreCase="false" negate="true" />
                    </conditions>
                    <action type="Rewrite" url="/{R:1}/index.cfm/{R:2}" />
                </rule>
            </rules>
        </rewrite>
        <defaultDocument>
            <files>
                <remove value="index.cfm" />
                <add value="index.cfm" />
            </files>
        </defaultDocument>
    </system.webServer>
</configuration>

Then, update your settings.ini.cfm file with the following settings and from the Admin > Reload Application:

siteidinurls=1
indexfileinurls=0

Your site should now be able to handle URLs that are missing index.cfm.

Cheers!

How to Create Dynamic Content Display Objects in Mura CMS with MuraFW1 Plugins

If you've ever created a MuraFW1 plugin for Mura CMS (which this article assumes by the way!), you may have wondered how to go about creating dynamic Content Display Objects. Doing so would enable an end-user to edit a page, go to the Content Objects tab, select Plugins from the Available Content Objects dropdown, select your plugin, then select your "dynamic display object" which would then fire off and return yet form field containing the dynamic list of options available to be assigned to the desired content display region.

Still with me? Great!

Ultimately, there's three main parts to this:

1. Create the display method, i.e., myDisplay

2. Then create an "OptionsRender" display method which follows the naming convention of myDisplayOptionsRender

3. Finally, we'll add the basic display method (i.e., myDisplay) to the config.xml.cfm's list of available displayObjects

1. Create The Display Method

In the pluginEventHandler.cfc, we can add our basic display method. Ultimately, we should eventually expect a JSON formatted variable to be passed in via $.event('params'). Obviously, we'll need to deserialize the JSON, and once we do that, we can do whatever we like with it. An easy way to pass this information over to FW/1 is to stuff any desired variables into the URL scope ... and then call the typical renderApp() method and let FW/1 take over from there. Check out our simple example below which is expecting to find "whateverID" to be in the unpacked params:

<cffunction name="dspWhatever" output="false" returntype="any">
    <cfargument name="$" hint="mura scope" />
    <cfscript>
        var local = {};

        // grab everything that's been passed in from OptionsRender() and unpack the JSON option values that were saved
        local.params = DeserializeJSON($.event('params'));

        // stuff selected WhateverID into the url scope so that fw1 will pick it up
        if ( StructKeyExists(local.params, 'whateverid') ) {
            url.whateverid = local.params.whateverid;
        };

        // something went wrong ... so let's not bomb everything
        if ( not StructKeyExists(url, 'whateverid') ) {
            return '';
        } else {
            return renderApp($,'public:main.default');
        };
    
</cfscript>
</cffunction>

2. Create An "OptionsRender" Method

Now for the magical part! Whatever you named your displayMethod, you simply append "OptionsRender" to the end of it. So if you have dspWidgets, then you would have dspWidgetsOptionsRender as an available method. In the example below, I'm creating a simple recordset which we'll then loop over to output the options and dynamically generate the option value which is a tilde (~) separated list where the last item in the list is a JSON formatted list of params...yes, the very same params our display method in step one is expecting to find!

<cffunction name="dspWhateverOptionsRender" output="false" returntype="any">
    <cfargument name="$" />
    <cfscript>
        var local = {};
        
        // this recordset could come from anywhere ... doesn't even have to be a recordset, could be anything that contains data that you want to grab options from
        local.rs = QueryNew('WhateverID,WhateverTitle,WhateverField', 'VarChar,VarChar,VarChar');

        QueryAddRow(local.rs, 1);
        QuerySetCell(local.rs,'WhateverID', 'anyid-1', 1);
        QuerySetCell(local.rs,'WhateverTitle', 'My Awesome Title', 1);
        QuerySetCell(local.rs, 'WhateverField', 'Hi Ho Cherry-O', 1);

        QueryAddRow(local.rs, 1);
        QuerySetCell(local.rs, 'WhateverID', 'anyid-2', 2);
        QuerySetCell(local.rs, 'WhateverTitle', 'Another Great Title', 2);
        QuerySetCell(local.rs, 'WhateverField', 'Knick Knack Paddy Whack', 2);
    
</cfscript>
    <cfsavecontent variable="local.str">
        <cfif local.rs.recordcount>
            <select name="availableObjects" id="availableObjects" class="dropdown">
                <!--- we're going to pack everything up into a tilde (~) separated list where the last item in the is a JSON formatted list of params to be passed over to the display method --->
                <cfoutput query="local.rs">
                    <option value="plugin~#HTMLEditFormat(Replace(WhateverTitle,'~','','ALL'))#~#$.event('objectid')#~{'whateverid':'#WhateverID#','anotherfield':'#WhateverField#'}">
                        #HTMLEditFormat(WhateverTitle)#
                    </option>
                </cfoutput>
            </select>
        <cfelse>
            <p><em>Please create some Whatevers first.</em></p>
        </cfif>
    </cfsavecontent>
    <cfreturn local.str />
</cffunction>

3. Add The Rendering Method To config.xml.cfm

The final step in all this is to add your basic displayMethod to your config.xml.cfm file so that it will be registered with Mura CMS. Once it is, then we should expect to see it show up in the Content Objects tab when someone selects our plugin.

<displayobjects location="global">
    <displayobject name="Display Whatever" displaymethod="dspWhatever" component="pluginEventHandler" persist="false" />
</displayobjects>

That's it! Hopefully this helps anyone else who is creating FW/1 plugins for Mura CMS.

Cheers!

Dynamically Define a Mura CMS Theme's Display Regions

A question came up recently regarding Mura CMS and how to alter the available content object display regions. This is actually quite simple to control from within the Admin area of the site by going to Site Settings > Select the Site > Select the Display Regions Tab and then choose the Number of Display Regions, select the Primary Display Region and define the Display Region Names as a carrot "^" delimited list.

However, this particular inquisitor was actually interested in how to control these settings from within a specific theme itself. Luckily, as with most things in Mura, it really isn't all that difficult to do.

Since this is not something we would want to happen everytime a page loads, it would probably work best to use the onApplicationLoad() method in the theme's eventHandler.cfc. This way, it will only be executed whenever the entire application is loaded. The next thing we need to figure out is what methods we need to call and how to tell Mura to save our settings.

So, as I've pointed other people in the past, most all of the important methods that comprise the Mura engine can be found under the /requirements/mura/ directory. Since we're dealing with Site Settings, we'll want to review the methods available to us under the 'settings' directory. There you'll find settingsManager.cfc among other files. Within this file, you'll be able to locate a method called update() which takes an argument called data which is required to be a struct/object. The data object should have a key which contains the siteid of the site we wish to edit the settings for. Then, we can update any of the available settings we wish!

Here's some code for you to play around with:

<cffunction name="onApplicationLoad">
    <cfargument name="$" />
    <cfscript>
        var local = {};
        
        // dynamically alter the available display regions from within a theme
        local.data = {
            siteID = $.siteConfig('siteid')
            , columnCount = 5
            , primaryColumn = 3
            , columnNames = 'Test^Left Column^Main Content^Right Column^Footer'
        };
        local.siteBean = $.getBean('settingsManager');
        local.siteBean.update(local.data);
    
</cfscript>
</cffunction>

If you're wondering what settings are available to you, simply do a dump of all the existing values:

<cfdump var="#$.siteConfig().getAllValues()#" />

Hope that helps someone else trying to update their Mura Site Settings from within the theme itself.

Cheers!

More Entries

© 2024, Stephen J. Withington, Jr.  |  Hosted by Hostek.com

Creative Commons License   |   This work is licensed under a Creative Commons Attribution 3.0 Unported License.