How do you decide what to use: UDF or Custom Tag? - coldfusion

WACK says:
If you feel you need to have lots of arguments, consider creating a CT instead.
...
CT are significantly more powerful and
flexible than custom functions. Try to
use UDFs for simple matters... Use CT
and Components for more involved
processes, especially those you can
think of as discrete actions rather
than simple "massaging"
Okay, but how are you usually making decisions? Interesting to know real-life practice and examples.
For me it happens when a function has many not-required arguments, so I have to call them myFunc(arg1="foo", arg2="bar"). Sometimes <cfmodule> syntax simply becomes more readable, but not always.
Other reason is that I don't like long (say, more than 2 screens of code) UDFs.
But all these thoughts are very subjective, that's why I'm interested in reading other people opinions. Maybe there's better rules for that?
Thanks in advance.

There a probably plenty of people in the community that would disagree with me, but here is how I generally think about it. If what you need to do involves output to the screen, and if it makes sense to "wrap" this around some other code or text, then a custom tag might be in order. In all other cases a UDF works fine and generally better. That being said, in close to 8 years of CF development, I really haven't ever came across a very good reason for a custom tag. I'm not saying the reasons don't exist, but I would say that they are rare.
If you have a very long UDF, is it safe to assume that this is something where you are outputting to the screen by calling this UDF (not really returning a value I mean)? I would consider breaking that UDF into smaller more manageable parts if that could make sense, but like you are alluding to, what matters in the end is what is the most readable, to you, your team and those who may come after you.
Update: Out of curiosity, which CFWACK book are you referring to (version and volume) and which page?

As I remember things, custom tags can be called at any time, where as UDFs have to be defined before you can use them. This makes custom tags easier generally. If you had huge libraries of UDFs it would be burdensome to make sure they are all included and potentially hard work for the server to parse them all (in olden days at least).
However UDFs can be used in a more compact way
<cfif myUdf(myVariable)>
The advantage of custom tags is that they can sit nicely with your markup.
<h1>Order Page</h1>
<cf_basket_nav>
<ul>
<cfloop ...>
<li>
<cf_basket_item item="#items[i]#">
</li>
</cfloop>
</ul>
</cf_basket_nav>
Generally nowadays I would have a 'utils' CFC with methods for what were your UDFs.

one consideration on the use of custom tags over udfs or cfc methods is when you find that a subroutine needs to be passed an array of child items, you can use nested custom tags to associate a child custom tag and its elements to a parent custom tag. this allows you to do very nice clean coding thats easy to read:
<cfmenubar ... >
<cfloop array="menuitems" ...>
<cfmenubaritem url="#i.url#">
#i.label#
</cfmenubaritem>
</cfloop>
</cfmenubar>
yes,yes i know we have nicer dhtml stuff like menus and tabs, this is simply to point out an example. you can use cfassociate in the custom tag to "pass" the attributes to the parent custom tag and then in the executionmode="end" access all the dynamically generated child items in the array of associated attributes. this is where you would loop and output the menu to the screen in this example.
also, as another commented, allows you to do some clever things... one thing in particular i use is that i set prefix="" and then i can essentially force simple html tags (like the <a> tag) to get kicked through a custom tag handler at runtime - so an html tag becomes intelligent at runtime... i do this so i can analize the href and the target attributes and decide if i want to display a pdf icon (or other mime type icon) next to the link... its pretty slick! this is especially helpful in a content management system or when 7you have html developers using dreamweaver or contribute and you want to have their tags fire smart coldfusion tags without them doing anything outside of standard html - the editor doesnt know any difference and they dont need to go into "code" view to make some fairly powerful functionality.
finally, in a custom tag you can choose to suppress output (or use a cache), so this can be very useful to wrap around chunck of dynamically generated html... access the thistag.generatedcontent variable in the executionmode EQ "end" mode
dont throw out the baby with the bathwater on this one ... i agree their usage is much less frequent since we have cfcs, however there is still some powerful functionality in custom tags... i usually have one or 2 in every application (and at least dozens of cfcs)
hth
jon

cfmodule has no advantage over functions; cfinvoke works just the same.
Of course, with cfimport you can enable a nice tidy namespaced CT syntax - and this is when custom tags are good: when working with clear open/close construct, or if nested logic is important.
For everything else, especially when returning results, functions are easier to handle.

Jeremy pointed to useful option: wrapping HTML by CT. But this feature seems to be so rarely used. Any way, it's a plus for CT.
Also I thought that I prefer function because I love cfscript coding. Few times I had to wrap legacy CT into UDF only to be able to use it at totally cfscript-ed page. It's a plus for UDF.

Simple reusable code can go into a UDF. This might include things like string formatting, data structure manipulation, etc etc.
For anything more complex than that, I would consider using CFCs instead of a custom tag. You'll be able to write much cleaner code in an OO model. You can always wrap the logic in your CFCs with a custom tag if you want to provide ease of use for someone who is more used to working with tags.

Not sure why I fell into this pattern, but in general I use Custom Tags (always with cfmodule) for anything that outputs HTML and UDFs for anything that merely returns simple data/objects. I realize that UDFs can do output as well, but I don't like my functions to have any side effects and this feels like one. For similar reasons, I now use Custom Tags anywhere where previously I would have used a cfinclude, since they provide encapsulation of data.

Related

Can JS-DOM test code that uses Tailwind's peer / peer-invalid mechanism?

Tailwind offers a feature where you can give an input element the peer class and then, in a sibling element use the peer-invalid: pseudoclass to apply conditional stylings. This is commonly used to provide helper text when a form field is not valid.
I don't see how this can be tested in JS-DOM though, as JS-DOM doesn't have access to the actual CSS when it is just rendering components in unit tests.
The information I have seen about getting JS-DOM to use CSS at all is kinda sketchy, so I was wondering if it's even worth trying to get it to evaluate a bunch of tailwind classes in a NextJS/Jest/RTL project. I'm using Tailwind 3 so it's not even like I have a big file full of generated classes I could try and pass to JS-DOM :/
So can it be done? (Note the hard fact please mods!!!)
(And, somewhat more subjectively, should it be done? Or is there a better way to approach this?)

Is it possible to add regular expressions (or, at least, wildcards) to list of custom html attributes?

WebStorm has inspection for html attribute names and allows to create list of exceptions for that rule. It's works fine, but it's not enough - some JS frameworks (like VueJS) comes with special syntax (for data binding, event binding and so on). It looks like this:
<input class="search-box__input"
type="text"
#keyup.enter="notifySearchRequested()"
v-el:input />
That syntax is well-known and predictable, so it might be perfect to add couple of regular expressions (or, maybe, wildcards - they more secure from performance point of view) to list of inspection exceptions in order to describe framework-specific attributes.
It sounds good for me, but I am not sure that it is possible with WebStorm :-(
So, can I deal with it with WebStorm (or, maybe, some plugin can help me)?

Scala / Lift - Trying to understand Lift's simultaneous claim to use valid html and propensity for lift: tags and tag rewriting in render

All of the Seven Things (http://seventhings.liftweb.net/) are certainly nice, but I was particularly enthusiastic about the claim in Templates (http://seventhings.liftweb.net/templates) that "Lift supports designer friendly templates."
As one of my steps in learning Lift's way of doing things I'm attempting to create a simple object creation form: take a few parameters, use them as constructor arguments, then stow the object away. After some research and experimentation, tho, I have two concerns:
There seems to be a considerable propensity for significantly rewriting/embellishing the template markup in snippets.
Forms don't seem to use valid or recognizable html elements.
What I'm basing this on:
The form examples/documentation seems all about special lift: tags. Exploring Lift suggests that a form should look like this: (http://exploring.liftweb.net/master/index-6.html)
<lift:Ledger.add form="POST">
<entry:description />
<entry:amount /><br />
<entry:submit />
</lift:Ledger.add>
I'm not sure that's even valid html5 and while it might be valid xhtml, it doesn't feel like that meets the spirit of having your templates look like real html for our designer friends. I read somewhere else (can't find it again) that we did have the option of using actual input tags, but then we wouldn't get some parts of Lift's fancy form wire-up or somesuch, the passage wasn't very clear on what exactly I'd be missing out and the examples don't seem interested in my writing a plain html form making a plain html post.
The code for a demo.liftweb.net example (1) suggests that your template should look like this (2)
<lift:surround with="default" at="content">
<div class="lift:PersonScreen"></div>
</lift:surround>
The code for PersonScreen snippet isn't exactly illuminating, either (3). There are several other examples of a template that has, e.g. only a ul tag in a particular location only to generate a whole series of complex li's with nested elements in the snippet. Sure, you can use xml in Scala and it reads tolerably, but it's still scattering your markup everywhere. This seems to violate the spirit of "designer friendly templates".
What I want to understand.
For a long time I've strictly followed two rules in my webapp development:
No markup in 'code' (controllers, business models).
No business logic in the templates whatsoever.
Idiomatic Lift seems to completely forego the first rule and completely miss the value of the second rule. These rules have served me well and I'm not ready to just follow along with the examples that seem to be violating them without understanding why its not going to create a mess. I want to understand why it's okay in Lift to have so much display code generated in the Snippets. I also want to understand why its okay that the markup in the templates so rarely reflects the output.
What I (think I) want:
I want all of my markup with very few, if any, exceptions to be in my templates. I want my snippets to do minimal template mangling, generally only replacing element text on "leaf" tags and possibly tweaking attribute values. I think I've done this for a reasonably complex display example and I suspect I could use the same technique to generate a vanilla html form and then handle the params myself. Is that what I need to do if I want my template to look like the end-result form?
Responses and any other thoughts, especially on understand the Lift mindset regarding this stuff, would be tremendously appreciated.
Thanks!
http://demo.liftweb.net/simple_screen?F674431078927QJVVYD=_
https://github.com/lift/examples/blob/master/combo/example/src/main/webapp/simple_screen.html
https://github.com/lift/examples/blob/master/combo/example/src/main/scala/net/liftweb/example/snippet/Wizard.scala#L94
EDIT
In response to #OXMO456. (Thanks for the response.)
I have, and they seem to just confirm my concerns: E.g. we start with:
Lift templates contain no executable code. They are pure, raw, valid HTML.
which is awesome. Then later:
The latter two mechanisms for invoking snippets will not result in valid Html5 templates.
and yet everyone seems to use the first of those two mechanisms. Also, it says:
Third, the designers don’t have to worry about learning to program anything in order to design HTML pages because the program execution is abstracted away from the HTML rather than embedded in the HTML.
But pretty consistently the example snippets like the one I referenced in the OP generate markup entirely programmatically. This seems counter to the goals (a) of having designer friendly templates so the designers don't have to be bothered with Freemarker markup and (b) separating display logic from business logic.
The second link is helpful and instructive, but it makes it pretty clear that this isn't The Lift Way. However, The Lift Way also seems to drag a whole load of markup generation into snippets, which is (I think) a huge compounding of markup and business logic. Is that The Lift Way?
Those are old-style tags, not designer-friendly tags.
<lift:MySnippet>
<b:field />
</lift:MySnippet>
becomes
<div class="lift:MySnippet">
<div class="field"></div>
</div>
Old-style Lift templates are valid XML, not XHTML - so you can't have unclosed tags or anything - this differentiates Lift from most frameworks, which treat templates as raw strings with bits of code intertwined throughout, without regard to tags or structure.
BTW, in old-style tags, those fields are all fabricated - they aren't part of some standard set of Lift tags. I could just as easily do:
<lift:MySnippet>
<frobnicate:blorb />
</lift:MySnippet>
as long as my snippet code is looking for that specific tag.
Lift doesn't allow any logic in your templates. All of the logic happens in your Snippet class. So for the designer-friendly example above, I might have a snippet class like this:
class MySnippet {
def render(in: NodeSeq): NodeSeq = ".field" #> Text("some text here")
}
which would yield this result:
<div>
<div class="field">some text here</div>
</div>
It's impossible to put any logic in Lift templates - all they can do is invoke Lift snippets, which are regular Scala classes where all of the work happens.
Lift discards the rule that you shouldn't have any display logic in your real code. Why? Because it makes for more reusable code, because Scala has powerful XML support baked into the language and because all of your logic is now treated as plain old Scala code.
If I define a Lift snippet called CurrentTime, I can simply drop that in to any template and it will display the current time - with old-school MVC frameworks, each action method needs to set the time as a page variable and then my templates would need to be modified to print it out. For more complicated logic, old-school frameworks would probably require a conditional in the templates. Lift doesn't allow that - all of your logic is regular Scala code, eligible for refactoring, easily testable, and compatible with modern IDE's.
In answer to you're "what I think I want" question, sure you can do that no problem. Lift is really all about choices, and understanding your use case. Often the samples you see with Lift intermingle code and markup, which is of course sub-optiomal. The important thing to note is that snippets conceptually are solely designed to produce markup, and render the view.
In addition, as Lift follows its view first paradigm the only thing that the view actually requires is a notation to outline which sections of markup you want to process in which rendering snippets. There are several ways, as illustrate by both the OP and "Bill", but personally I prefer:
<div lift="YourSnippet.method">
<p>Some other code</p>
</div>
This is preferable because you're then not culturing up the class attribute which (IMO) can be confusing for designers. Lift can be very designer friendly, but I think the main problem here is that you have to be both disciplined when writing your snippets whilst ignoring many of the samples available today which mix Scala and markup.
You may also be interested in this post ( http://blog.getintheloop.eu/2011/04/11/using-type-classes-for-lift-snippet-binding/ ); using this sort of pattern you can define decoupled, reusable parts of rendering logic whilst keeping your business logic safely out of the snippets.
Finally, and without wanting to shamelessly promote my own product, but I specifically went out of my way to not use any mixed Scala xml literals in my example code for Lift in Action (other than to illustrate that its possible), so perhaps it might be of assistance if you're looking at Lift ( http://manning.com/perrett/ )

Django: assign accesskey to label instead of select

i'm developing a site that must be as accessible as possible. While assigning the accesskeys to my form fields with
widget=FieldWidget(attrs={'accesskey':'A'})
i found out that the w3c validator won't validate an xhtml strict page with an accesskey in a select tag. Anyway i couldn't find a way to assign an accesskey to the label related to the select field (the right way to make the select accessible). Is there a way to do so?
Thanks
Interesting question. HTML 4.01 also prohibits accesskey in a select.
I believe the Short Answer is: Not in standard Django.
Much longer answer: I looked at the code in django/forms/fields.py and .../widgets.py and the label is handled strictly as a string (forced to smart_unicode()). Four possible solutions come to mind, the first three are not pretty:
Ignore the validation failure. I hate doing this, but sometimes it's a necessary kludge. Most browsers are much looser than the DTDs in what they allow. If you can get the accesskey to work even when it's technically in the wrong place, that might be the simplest way to go.
Catch the output of the template and do some sort of ugly search-and-replace. (Blech!)
Add new functionality to the widgets/forms code by MonkeyPatching it. MonkeyPatch django.forms.fields.Field to catch and save a new arg (label_attrs?). MonkeyPatch the label_tag() method of forms.forms.BoundField to deal with the new widget.label_attrs value.
I'm deliberately not going to give more details on this. If you understand the code well enough to MonkeyPatch it, then you are smart enough to know the dangers inherent in doing this.
Make the same functional changes as #3, but do it as a submitted patch to the Django code base. This is the best long-term answer for everyone, but it's also the most work for you.
Update: Yoni Samlan's link to a custom filter (http://www.djangosnippets.org/snippets/693/) works if you are generating the <label> tag yourself. My answers are directed toward still using the full power of Forms but trying to tweak the resultant <label>.

Strategy/recommendations of using CFPARAM

Each time when using cfparam I have a kind of feeling that I put it in the wrong place or generally mis-using.
Consider this example, say we need to show the new entity form (with default input values):
<cfparam name="form.attachLink" default="" />
<input type="text" name="attachLink" value="#HTMLEditFormat(form.attachLink)#" />
Even this simple one makes me thinking about following questions on cfparam:
Should I use it before exact usage place? Wont it break the Model/View idea?
Or should I group them somewhere in model template, or maybe on top of the view?
When paramin' the form data, maybe it's better to use StructKeyExists(form, "attachLink")? Sure, I do this (plus validation) when processing the submitted form, but for the fresh form this can be useful too -- for safety-paranoid people like me.
Where else it makes sense to use this tag? I know one really useful place: custom tags, though they itself become more and more legacy too.
Thanks.
At the risk of sounding unhelpful: "It depends."
I think it's a bit complicated by the fact that CFPARAM can be used for setting default values as well as validating the type of a variable and throwing an error when it doesn't match. That said, I almost always use it just for the former. With the latter, a lot of that has been subsumed by arguments to components.
One of the more useful uses is on the action page for a form with checkboxes.
<cfparam name="form.myCheckbox" default="" />
Since it's valid for none of the checkboxes to be checked on the form, this prevents me from having to create special validation to see if the form variable exists before using it and, since I'm almost always treating it as a list, an empty-string is still valid for list functions.
As for where to place them, when I use them I almost always put them at the top of the cfm file, but that's probably just a style thing. If you sprinkle them in your code I think you're going to run into cases where the variable is going to be set and you don't know where it happened.
Of course, I'm using Model-Glue pretty much exclusively these days. Not much use for CFPARAM.
If you are going to reference the variable in a form value, you should use cfparam with a reasonable default (even blank) to ensure that the variable exists. However, if the variable is only being referenced upon form processing, I would skip cfparam (unnecessary as you're not setting a value in the form) and instead use structKeyExists(scope, "key") in the form processing step.
In an MVC framework, you may have an option to set your default values in another manner. In this case, you are most likely not referencing the form scope directly, but rather a framework managed scope. Fusebox uses the 'event' scope. On page load, the Fusebox framework merges both the URL and FORM scope together into the EVENT scope. If you are concerned about 'breaking MVC', I recommend setting up, and/or testing for the necessary variables in your framework's scope (in my case EVENT) in the MVC controller (using your framework's recommended method) before you display the form in the view. Most likely you won't need cfparam for this.
I think of cfparam the same way I think of variable declarations. I alway declare my variables as close as possible to where I'm going to use the variable. In coldfusion world, I use the cfparam tag right before the cfform tag.
It sounds like you're using an MVC framework. I don't see how this impacts the use of cfparam. The model is where you get the data. CFParam isn't specific to the model.