fusebox 5.5 noxml folder name problems - view

I am having trouble with fusebox 5.5 noxml and circuits...
I have a structure that looks like this.
controller
app.cfc
model
main
act_comm_main.cfm
monkey
act_something_else.cfm
view
main
dsp_comm_main.cfm
monkey
dsp_somethingElse.cfm
In the app.cfc file I have this:
<cffunction name="postfuseaction">
<cfargument name="myFusebox" />
<cfargument name="event" />
<!--- do the layout --->
<cfset myFusebox.do( action="layout.lay_template" ) />
</cffunction>
<cffunction name="main">
<cfargument name="myFusebox" />
<cfargument name="event" />
<!--- do model fuse --->
<cfset myFusebox.do( action="moneky.act_somethingElse" ) />
<!--- do model fuse --->
<cfset myFusebox.do( action="main.act_comm_main" ) />
<!--- do display fuse and set content variable body --->
<cfset myFusebox.do( action="main.dsp_comm_main", contentvariable="body" ) />
</cffunction>
</cfcomponent>
This doesn't work. but if I change it to have the view folder named: mainPages so and then change the cfset myFusebox. do to look at mainPages.dsp_comm_main (it comes up) but in the instance above it give me this error:
undefined Fuseaction
You specified a Fuseaction of dsp_comm_main which is not defined in
Circuit main.
I remove the parsed files and let fusebox rebuild but I still get this error.
So I know how to work around it by naming my directories different between the model and view folders but why is this happening and what can I do to get to resolve same named directories across the model view?

This is because in Fusebox models and views are just a convention to implement MVC. Technically they just a circuits, explicit or implicit, doesn't matter.
Circuit name must be unique within the application, so you have to name the folders differently.
Personaly I've used naming like vMain/mMain, vMonkey/mMonkey for more complex apps with many view circuits. For simpler apps it could be enough to have just layout and display view circuits, this way models can be named without prefix.

Related

Cocoa Scripting: "whose clause" cannot access certain properties

I am working on making my application scriptable. I struggle with the "whose" filter clause.
I want to make this work, but while name can be used, country can not:
tell application "myapp"
get every city whose name is "Berlin" -- works
get every city whose country is "Germany" -- error -1700 (Can’t make country into type specifier)
end tell
The relevant parts of the sdef look like this:
<class name="application" code="capp">
<cocoa class="NSApplication"/>
<element type="city">
<cocoa key="allCities"/>
<accessor style="index"/>
</element>
<class name="city" code="Citi" plural="cities">
<cocoa class="ScriptableCity"/>
<property name="name" code="pnam" type="text" access="r">
<cocoa key="name"/>
</property>
<property name="country" code="Ctry" type="text" access="r">
<cocoa key="country"/>
</property>
</class>
What must I do to make country work with "whose" as well? Apparently, the "whose" clause wants a type specifier, not a property name, but I can't make sense of this.
I have implemented indicesOfObjectsByEvaluatingObjectSpecifier:, but that only gets called for name, not for country.
Oh, I had it all wrong. My program code is fine. The issue is caused by the fact that I also have a class named country. So AppleScript, looking at the outmost scope for the identifier first, finds the class country and tries to use that for the comparison. Had the error message included the word "class", this would have been easier to detect, probably.
There are now two solutions:
Rename the property in the Sdef so that it does not clash with the class name any more, e.g. to country name.
Use of it in order to change the scope for the lookup of the identifier, like this:
get every city whose country of it is "Germany"
It is also important to make sure that if the same property name is used in several classes, they all use the same 4-char type code. Otherwise this problem can surface as well.

Is there a way to conditionally include attributes in custom JSP tag?

Lets say I have a field that can take 3 attributes
<myTag a="something" b="something" c="something" />
Let's say I want to only include those a,b,c attributes when a variables are not blank. So with EL it becomes something like this
<myTag a="${varA}" b="${varB}" c="${varC}" />
In the case that one or more of the variables are blank (say varB is empty) I'm getting output like:
<myTag a="a val" b c="c val" />
So b is still there, but passing a blank value.
This can cause problems with some spring <form:etc> tags if an attribute is blank (say itemLabel on form:options for example)
What if I don't want that? Is there an easy way to have the attribute not show up altogether?
I get that I can do
<c:if test="${empty b}">
<myTag a="${varA}" c="${varC}" />
</c:if>
But that means we need a giant decision tree as the number of attributes increase if each one can possibly be blank.
Does anyone know a better way to do this?

CFWheels "Hello Database" in true MVC format

The "Hello Database" example at cfwheels.org includes only a controller and views. What would the app look like if it included a model? Total beginner here, and I want to know when and how to use a model.
http://cfwheels.org/docs/1-3/chapter/beginner-tutorial-hello-database
To make sure this is a programming question, what would the model code look like in the Hello World app? I'm guessing just a line or two.
First of all, the example app follows all conventions and it is very simple application so there is no need to use model.
But if you want to use model for that then it would go like this:
In model folder,
create a CFC file with name User.cfc and add following code in it
<cfcomponent extends="Model">
<cffunction name="init">
</cffunction>
</cfcomponent>
You can see there is nothing in the init function as there is no need to do anything as of now. But in case you want something you can add
<cfset table(name="users")>
in the init function.

How to declaratively deploy a localized datetime field with validation?

The following column definition DOES work.
<Field ID="{F4313C31-C8DD-4917-98A9-0DE886177758}"
Type="DateTime"
Name="ExpirationDate"
DisplayName="Limited until (if necessary)"
StaticName="ExpirationDate"
Group="SomeGroup"
Required="FALSE"
Format="DateOnly"
FriendlyDisplayFormat="Disabled"
CalType="0">
<Validation Message="Please select a date in the future.">=[Limited until (if necessary)]>TODAY()</Validation>
But of course I do not want to use the display name in my validation formula.
Moving closer to production any display name will be moved a resx file anyway.
And using a resx file I end up with the same error as I encountered before when I was trying to use the internal field name instead of the display name.
The error is: The formula cannot refer to another column. Check the formula for spelling mistakes or update the formula to reference only this column.
This is what SharePoint does itself when creating a column via the UI:
<Field Type="DateTime" DisplayName="RS Expiration Date" Required="FALSE" EnforceUniqueValues="FALSE" Indexed="FALSE" Format="DateOnly" FriendlyDisplayFormat="Disabled" ID="{15380d60-50d7-4ce1-b21b-92695f0c0811}" SourceID="{8086fd7d-ca0b-4258-9352-f166615b6159}" StaticName="RSExpDate" Name="RSExpDate" ColName="datetime2" RowOrdinal="0" CalType="0" Version="1">
<Validation Message="Please enter a future date." Script="function(x){return SP.Exp.Calc.valid(SP.Exp.Node.f('GT',[SP.Exp.Node.a(0),SP.Exp.Node.f('TODAY',[])]),x)}">=RSExpDate>TODAY()</Validation>
<ValidationDisplayNames>=[RS Expiration Date]>TODAY()</ValidationDisplayNames>
Obviously there's a lot of information in there you won't need.
The interesting part is the validation part. It is using "ValidationDisplayNames" instead of "Validation". Still the latter too does only work with display names.

How to properly implement a shared cache in ColdFusion?

I have built a CFC designed to serve as a dynamic, aging cache intended for almost everything worth caching. LDAP queries, function results, arrays, ojects, you name it. Whatever takes time or resources to calculate and is needed more than once. I'd like to be able to do a few things:
share the CFC between applications
define the scope of the cache (server / application / session / current request only)
use different cache instances at the same time, in the same request
be independent from CFCs using the cache component
generally adhere to common sense (decoupling, encapsulation, orthogonality, locking)
I would of course be using a different cache instance for every distinct task, but I'd like to be able to use the same CFC across applications. The cache itself is (what else) a Struct, private to the cache instance. How would I properly implement caching and locking when the scope itself is subject to change?
For locking, I use named locks ('CacheRead', 'CacheWrite') currently, this is safe
but strikes me as odd. Why would I want a server-wide lock for, say, a session-only operation? (Yes, maybe this is academic, but anyway.)
Passing in the APPLICATION scope as a reference when I want application level caching also seems the wrong thing to do. Is there a better way?
Okay - since I misunderstood your question initially I've deleted my previous answer as to not cause any further confusion.
To answer your question about locking:
Named locks should be fine because they don't have to always have the same name. You can name them dynamically depending on what cache you are accessing. When you need to access an element of the private struct you could do something like have the named lock use the key as its name.
This way, the only time a lock would have an effect is if something was trying to access the same cache by name.
I understand your desire to avoid passing in the actual scope structure that you want to cache to, but your alternatives are limited. The first thing that comes to mind is just passing the name (a string) of the scope you want your cache stored in, and evaluating. By its nature, evaluation is inefficient and should be avoided. That said, I was curious how it might be accomplished. I don't have your code so I just made a dirt-simple "storage" abstraction CFC (skipped caching, as it's irrelevant to what I want to test) here:
cache.cfc:
<cfcomponent>
<cfset variables.cacheScope = "session" /><!--- default to session --->
<cfset variables.cache = ""/>
<cfscript>
function init(scope){
variables.cacheScope = arguments.scope;
return this;
}
function cacheWrite(key, value){
structInsert(evaluate(variables.cacheScope),arguments.key,arguments.value,true);
return this;
}
function cacheRead(key){
if (not structKeyExists(evaluate(variables.cacheScope), arguments.key)){
return "";
}else{
variables.cache = evaluate(variables.cacheScope);
return variables.cache[arguments.key];
}
}
</cfscript>
</cfcomponent>
And a view to test it:
<!--- clear out any existing session vars --->
<cfset structClear(session)/>
<!--- show empty session struct --->
<cfdump var="#session#" label="session vars">
<!--- create storage object --->
<cfset cacher = createObject("component", "cache").init("session")/>
<!--- store a value --->
<cfset cacher.cacheWrite("foo", "bar")/>
<!--- read stored value --->
<cfset rtn = cacher.cacheRead("foo")/>
<!--- show values --->
<cfdump var="#rtn#">
<cfdump var="#session#" label="session vars">
Off topic: I like to write my setter functions to return "this" [as seen above] so that I can chain method calls like jQuery. Part of the view could just as easily been written as:
<cfset rtn = createObject("component", "cache")
.init("session")
.cacheWrite("foo", "bar")
.cacheRead("foo")/>
It's interesting that this is possible, but I probably wouldn't use it in production due to the overhead cost of Evaluate. I'd say that this is valid enough reason to pass in the scope you want to cache into.
If you're still bothered by it (and maybe rightly so?), you could create another CFC that abstracts reading and writing from the desired scope and pass that into your caching CFC as the storage location (a task well-suited for ColdSpring), that way if you ever decide to move the cache into another scope, you don't have to edit 300 pages all using your cache CFC passing in "session" to init, and instead you can edit 1 CFC or your ColdSpring config.
I'm not entirely sure why you would want to have single-request caching though, when you have the request scope. If what you're looking for is a way to cache something for the current request and have it die shortly afterward, request scope may be what you want. Caching is usually more valuable when it spans multiple requests.

Resources