29 Replies Latest reply on Dec 20, 2012 3:26 PM by BreakawayPaul

    Newb question about Application.cfc vs .cfm

    BreakawayPaul Level 2

      Sorry for this total newb question that's probably been covered a bazillion times, but I'm having some trouble getting things to work.  I should know all this stuff, as I've taken the CF9 advanced training, but when you have 60,000 pages worth of content back at the office waiting to be converted to a new design, there isn't much time to practice what you learned in class.

       

      A lot of my office's website is leftover from when we were running CF 6.1, so everything uses Application.cfm files.  Now that we're running CF8 (and may soon move to something even newer), I'd like to get everything modernized, including getting my Application.cfm stuff into an Application.cfc file.  One of the reasons I want to do this is because I have a few apps that I want to use OnRequestStart() methods for.

       

      My problem stems from the fact that our Application.cfm file does a lot of things like setting global variables, doing queries, and other things that I can't seem to get to work inside an Application.cfc file.  Particularly odd is the fact that I recently set up a CF10 site for my wife's business's websites and was able to get Application.cfc working without much trouble, leading me to suspect a setup problem with my office.

       

      I tried following the guide on Hostek's forum, but to no avail.  I can't seem to include the contents of our old Application.cfm file in the new cfc.

       

      Any tips?

        • 1. Re: Newb question about Application.cfc vs .cfm
          Adam Cameron. Level 5

          Yep, first tip: show us the code that isn't working, and explain in what way it's not working, ie: what you expect it to do, and what it's doing instead.

           

          Other than that, your question is too nebulous to be able to answer properly beyond "yeah, it should all work".

           

          --

          Adam

          • 2. Re: Newb question about Application.cfc vs .cfm
            Dan Bracuk Level 5

            I suggest preserving the Application.cfm files unless you have a specific reason to convert them.  What's that old saying?  If it ain't broke, don't fix it.

            • 3. Re: Newb question about Application.cfc vs .cfm
              BKBK Adobe Community Professional & MVP

              As Adam has suggested, if you show us your Application.cfm, I am sure you will get many suggestions pronto.

              • 4. Re: Newb question about Application.cfc vs .cfm
                BreakawayPaul Level 2

                Well as far as code goes I basically just copied an Application.cfc example template from a website and edited it.

                 

                What I have now is basically this:

                 

                <cfcomponent>

                <cfscript>

                this.name = "hepcms";

                this.sessionManagement = "Yes";

                this.sessionTimeout = CreateTimeSpan(0,1,0,0);

                this.setClientCookies = "Yes";

                </cfscript>

                 

                <cffunction name="onRequestStart">

                <cfargument name="requestname" required=true />

                <cfinclude template="application.cfm">

                </cffunction>

                </cfcomponent>

                 

                Thing is, I'm not sure I even need an application name, since this is just the CMS for the website.

                 

                @Dan

                 

                The reason I'd like to do this change is because I want to use the OnRequestStart feature in Application.cfc.  Our CMS used to have a cflogin, and I would record who logged in and at what time/date.  Now we've been forced to switch to a central type of authentication that works similar to password protected directories. 

                 

                Once we log in to access the CMS folder, credentials are contained in GetAuthUser().  I want to still be able to see who logged in and when, but I can't use the old method.

                 

                Also, with my wife's website, I was able to use Application.cfc to add common headers and footers to each page without having the includes directly on the pages.  This is something else I'd like to implement.

                • 5. Re: Newb question about Application.cfc vs .cfm
                  Dan Bracuk Level 5

                  You do need an application name.

                   

                  Get rid of the <cfinclude template="application.cfm"> tag.

                  • 6. Re: Newb question about Application.cfc vs .cfm
                    BKBK Adobe Community Professional & MVP

                    Dan Bracuk wrote:

                     

                    You do need an application name.

                    There is an application name. Unless you wish to emphasize the point.

                     

                    Get rid of the <cfinclude template="application.cfm"> tag.

                    No need to get rid of it. As long as the file name begins with small-letter 'a' and the file contains appropriate code.

                    • 7. Re: Newb question about Application.cfc vs .cfm
                      BreakawayPaul Level 2

                      I have the application name in there because there was one in the sample.

                       

                      However, the include doesn't work.  Any variables set in that include are undefined.  Perhaps I need to go around and reference them all as #variables.variable_name# for them to work?

                       

                      EDIT: It turns out that the variables aren't all that's missing.  Any results from queries done in application.cfm are also not available on the pages.

                      • 8. Re: Newb question about Application.cfc vs .cfm
                        BKBK Adobe Community Professional & MVP

                        What does the included code look like?

                        • 9. Re: Newb question about Application.cfc vs .cfm
                          BKBK Adobe Community Professional & MVP

                          BreakawayPaul wrote:

                           

                          However, the include doesn't work.  Any variables set in that include are undefined. 

                          Did you save the file as Application.cfc, with capital A.

                          • 10. Re: Newb question about Application.cfc vs .cfm
                            BreakawayPaul Level 2

                            Everything's lowercase.  It's a Windows machine, so not case sensitive.

                             

                            This is what's in the included file:

                             

                            <cfquery name="userdata" datasource="hepoffice">

                            SELECT usernm, user_email, admin

                            FROM users

                            WHERE usernm = '#listlast(GetAuthUser(),"\")#'

                            </cfquery>

                            <cfif userdata.recordcount eq 0>

                            <cflocation url="noaccess.html">

                            </cfif>

                            <cfset rights = userdata.admin>

                             

                            <cffile action="read" file="D:\inetpub\fhwaroot_test\includes\hep\acronyms.xml" variable="myxml" />

                            <cfset variables.acrXML = XmlParse(myxml) />

                            <cfset variables.acrList = acrXML.acronyms.XmlChildren />

                            <cfset variables.acrListSize = ArrayLen(acrList) />

                            <cfset variables.acrQuery = QueryNew("id, name, old, new") />

                            <cfset variables.acrTemp = QueryAddRow(acrQuery, #acrListSize#) />

                            <cfloop index="i" from="1" to="#acrListSize#">

                            <cfset variables.acrTemp = QuerySetCell(acrQuery, "id", #i#, #i#) />

                            <cfset variables.acrTemp = QuerySetCell(acrQuery, "name", #acrXML.acronyms.acronym[i].name.XmlText#, #i#) />

                            <cfset variables.acrTemp = QuerySetCell(acrQuery, "old", #acrXML.acronyms.acronym[i].old.XmlText#, #i#) />

                            <cfset variables.acrTemp = QuerySetCell(acrQuery, "new", #acrXML.acronyms.acronym[i].new.XmlText#, #i#) />

                            </cfloop>

                            • 11. Re: Newb question about Application.cfc vs .cfm
                              BKBK Adobe Community Professional & MVP

                              BreakawayPaul wrote:

                               

                              Everything's lowercase.  It's a Windows machine, so not case sensitive.

                              Use the file name Application.cfc, even on Windows.

                              • 12. Re: Newb question about Application.cfc vs .cfm
                                BKBK Adobe Community Professional & MVP

                                BreakawayPaul wrote:

                                <cfset rights = userdata.admin>

                                 

                                <cffile action="read" file="D:\inetpub\fhwaroot_test\includes\hep\acronyms.xml" variable="myxml" />

                                <cfset variables.acrXML = XmlParse(myxml) />

                                <cfset variables.acrList = acrXML.acronyms.XmlChildren />

                                <cfset variables.acrListSize = ArrayLen(acrList) />

                                <cfset variables.acrQuery = QueryNew("id, name, old, new") />

                                <cfset variables.acrTemp = QueryAddRow(acrQuery, #acrListSize#) />

                                <cfloop index="i" from="1" to="#acrListSize#">

                                <cfset variables.acrTemp = QuerySetCell(acrQuery, "id", #i#, #i#) />

                                <cfset variables.acrTemp = QuerySetCell(acrQuery, "name", #acrXML.acronyms.acronym[i].name.XmlText#, #i#) />

                                <cfset variables.acrTemp = QuerySetCell(acrQuery, "old", #acrXML.acronyms.acronym[i].old.XmlText#, #i#) />

                                <cfset variables.acrTemp = QuerySetCell(acrQuery, "new", #acrXML.acronyms.acronym[i].new.XmlText#, #i#) />

                                </cfloop>

                                If you wish these variables (included in Application.cfc) to be available to every requested page, then you should store them in the request scope instead.

                                • 13. Re: Newb question about Application.cfc vs .cfm
                                  BreakawayPaul Level 2

                                  Wow, that was a pain.  I had to find EVERY variable and scope it.  But at least it works!  Thanks.

                                  • 14. Re: Newb question about Application.cfc vs .cfm
                                    Adam Cameron. Level 5

                                    BKBK wrote:

                                     

                                    BreakawayPaul wrote:

                                    <cfset rights = userdata.admin>

                                     

                                    <cffile action="read" file="D:\inetpub\fhwaroot_test\includes\hep\acronyms.xml" variable="myxml" />

                                    [...]

                                    If you wish these variables (included in Application.cfc) to be available to every requested page, then you should store them in the request scope instead.

                                     

                                    Or, use the onRequest() interceptor to include the requested template, then it will get executed in the same memory space as Application.cfc, so its variables scope will be shared throughout the request. IE: the request will use Application.cfc's variables scope.

                                     

                                    --

                                    Adam

                                    • 15. Re: Newb question about Application.cfc vs .cfm
                                      Adam Cameron. Level 5

                                      I suggest preserving the Application.cfm files unless you have a specific reason to convert them.  What's that old saying?  If it ain't broke, don't fix it.

                                       

                                      Disagree. If there's major upheaval (like an upgrade from 6.1 to 8) that's going to necessitate a full retest anyhow, it's precisely the time to modernise code like this. Especially if one wants to leverage the new features it offers. In this case it's also a fairly straight-forward migration, too.

                                       

                                      Application.cfm is dead, and everyone who's in the position to should have moved off it by now. We're not talking about something that came out in the last version of CF... it's been around for seven years now.

                                       

                                      --

                                      Adam

                                      • 16. Re: Newb question about Application.cfc vs .cfm
                                        BreakawayPaul Level 2

                                        Adam Cameron. wrote:

                                         

                                        Or, use the onRequest() interceptor to include the requested template, then it will get executed in the same memory space as Application.cfc, so its variables scope will be shared throughout the request. IE: the request will use Application.cfc's variables scope.

                                         

                                         

                                        I should probably figure out how to do that, because I just noticed that any queries done in the included application.cfm (which I'll likely rename) are not accessible on any of the pages in the application.

                                        • 17. Re: Newb question about Application.cfc vs .cfm
                                          BKBK Adobe Community Professional & MVP

                                          BreakawayPaul wrote:

                                           

                                          I should probably figure out how to do that, because I just noticed that any queries done in the included application.cfm (which I'll likely rename) are not accessible on any of the pages in the application.

                                          You needed <cfquery name="request.userdata" datasource="hepoffice">

                                          • 18. Re: Newb question about Application.cfc vs .cfm
                                            BreakawayPaul Level 2

                                            I love it!  Got the updated CMS working now.

                                             

                                            In the old CMS, I used to keep the name of the last logged-in user in the database, and that would display on the front page when the next person logged in.  That way if something weird got changed, you knew who to ask about it.

                                             

                                            With no cflogin, I'm hoping I can use something like OnSessionStart() (or End()) to do this same thing, but my trial and error hasn't been going well.

                                             

                                            Should I be using OnSession or OnApplication?  And how does the Session timeout affect things?  If no one requests a page before the session timeout occurs, does the session end?  Not that it matters, because the way we're authenticating, it would just renew the credentials.

                                            • 19. Re: Newb question about Application.cfc vs .cfm
                                              BKBK Adobe Community Professional & MVP

                                               

                                              BreakawayPaul wrote:

                                               

                                              In the old CMS, I used to keep the name of the last logged-in user in the database, and that would display on the front page when the next person logged in.  That way if something weird got changed, you knew who to ask about it.

                                               

                                              With no cflogin, I'm hoping I can use something like OnSessionStart() (or End()) to do this same thing, but my trial and error hasn't been going well.

                                               

                                              They way you describe it, userLastLoggedIn is user-dependent, hence a session variable. For example, when I log in, my value of session.userLastLoggedIn is the user who last logged in before me. If you're the next to log in after me, your value of session.userLastLoggedIn will be me.

                                               

                                              The variable has to be available thoughout my session. So the best place to set it is in onSessionStart.

                                              And how does the Session timeout affect things?  If no one requests a page before the session timeout occurs, does the session end?  Not that it matters, because the way we're authenticating, it would just renew the credentials.

                                               

                                              You have set the sessiontimeout value at 1 hour. It means that a user's session will end if the user doesn't make any requests to the server in a period of 1 hour. Users don't share sessions. The server gives each user his own. Therefore, if after logging in you go away for an hour, the server will time your session out. That there are a thousand other users active on the server has no effect on your session.

                                              • 20. Re: Newb question about Application.cfc vs .cfm
                                                BreakawayPaul Level 2

                                                Thanks.  I'll play with getting the last logged in user thing to work tomorrow.  Today it told me that the last user (me) logged in back in December of 1899.  Either the webserver has a time setting problem or something else is wrong.   Besides, I only look like I was around in 1899.

                                                 

                                                The session timeout is pretty irrelevant for us.  They've set up some sort of password-protected directory where if you visit the CMS (which is on an intranet server) in IE, your network credentials are retained, and you're let right in.  I control access with a database query - if you're in the database, you get in.  If you're not, you get sent to an HTML page telling you that you don't have access to the system.

                                                 

                                                Since the credentials are always "there" from IE, nothing seems to ever time out, even if I make the session time 10 seconds.  Firefox users get a login box, but their session never seems to timeout either.  I guess I'll leave the session timeout at an hour, since it won't hurt anything.

                                                • 21. Re: Newb question about Application.cfc vs .cfm
                                                  BreakawayPaul Level 2

                                                  Totally works now!

                                                   

                                                  I had to work around a weird Access (probably) thing.  I was entering the last logged in time/date as #Now()# and then querying it.  I used timeformat() to get the time out of that, then dateformat() to get the date.  But doing that kept giving me the correct time but December 1899 for the date.

                                                   

                                                  To fix this I had to use two separate fields, and update them differently.  After trying it probably two dozen different ways, this is the only thing I could get to work:

                                                            lastlogintime = <cfqueryparam value="#Now()#" cfsqltype="cf_sql_time">

                                                          , lastlogindate = <cfqueryparam value="#dateformat(Now(),"mm-dd-yyyy")#" cfsqltype="cf_sql_date">

                                                   

                                                  In Access both field types are Date/Time.

                                                   

                                                  Hopefully once we get MSSQL working properly, things like that will stop being an issue.

                                                  • 22. Re: Newb question about Application.cfc vs .cfm
                                                    Dan Bracuk Level 5

                                                    Sounds more like you doing something wrong than it does a wierd access thing.  Breaking a timestamp into two fields makes sense in some situations, but not yours.  But if you are going to do it, you may as well do it properly and send a date to your date field, not a string.

                                                    • 23. Re: Newb question about Application.cfc vs .cfm
                                                      BKBK Adobe Community Professional & MVP

                                                      BreakawayPaul wrote:

                                                       

                                                      Today it told me that the last user (me) logged in back in December of 1899.  Either the webserver has a time setting problem or something else is wrong.   Besides, I only look like I was around in 1899.

                                                      When you store just the time in a datetime variable, ColdFusion will use December of 1899 as the default month and year. This code snippet shows you what I mean:

                                                       

                                                      <cfset t = parseDateTime("9:30 AM")>

                                                      <cfoutput>#t#</cfoutput>

                                                       

                                                      Since the credentials are always "there" from IE, nothing seems to ever time out, even if I make the session time 10 seconds.  Firefox users get a login box, but their session never seems to timeout either.  I guess I'll leave the session timeout at an hour, since it won't hurt anything.

                                                      Should you ever wish to link login to session timeout, then consider the setting this.loginStorage="session".

                                                      • 24. Re: Newb question about Application.cfc vs .cfm
                                                        BKBK Adobe Community Professional & MVP

                                                        BreakawayPaul wrote:

                                                         

                                                        To fix this I had to use two separate fields, and update them differently.  After trying it probably two dozen different ways, this is the only thing I could get to work:

                                                                  lastlogintime = <cfqueryparam value="#Now()#" cfsqltype="cf_sql_time">

                                                                , lastlogindate = <cfqueryparam value="#dateformat(Now(),"mm-dd-yyyy")#" cfsqltype="cf_sql_date">

                                                         

                                                        In Access both field types are Date/Time.

                                                         

                                                        Hopefully once we get MSSQL working properly, things like that will stop being an issue.

                                                        As temporary solutions go, this one is quite good.

                                                        • 25. Re: Newb question about Application.cfc vs .cfm
                                                          BreakawayPaul Level 2

                                                          @Dan

                                                           

                                                          My first attempt was to just stick #Now()# onto a date/time field with no formatting.  Somehow that got me the 1899 thing.  I tried many iterations until finally stumbling across the above solution.  I don't get why a plain #Now()# can't be used for both time and date, unless the date/time data type of Access is screwy.

                                                           

                                                          I didn't try storing it as text.  Maybe I should have just to see what happened.

                                                          • 26. Re: Newb question about Application.cfc vs .cfm
                                                            Dan Bracuk Level 5

                                                            If you insert now() into a table, select the field with a cf query, and cfdump that query, do you get the proper date and time?

                                                            • 27. Re: Newb question about Application.cfc vs .cfm
                                                              BreakawayPaul Level 2

                                                              I get this:

                                                               

                                                              2012-12-20 15:27:04.0

                                                               

                                                              Which seems right.

                                                              • 28. Re: Newb question about Application.cfc vs .cfm
                                                                Dan Bracuk Level 5

                                                                So when you saw something else earlier, it wasn't necessarily bad data.

                                                                • 29. Re: Newb question about Application.cfc vs .cfm
                                                                  BreakawayPaul Level 2

                                                                  Yes and no.  When I queried the database column I was having trouble with before, it started with 1899-12.

                                                                   

                                                                  I fiddled around some and determined that it was somehow the way the update was being done.  I took the <cfqueryparam> off of the #Now()# in the query, and now I get the results I expect.  BUT I didn't get it right away.  I had to close the browser completely and log back in before it showed up the right way.  Maybe it was a session or a caching thing.

                                                                   

                                                                  Anyway, I FINALLY have one database field for the timestamp!