As I wrote in an earlier message, I want to avoid that VS Code
's addon Prettier
indent lines where I use WC tags starting with <%
. The indentation happens because Prettier doesn't see any matching closing tags. I have spent some time on this, and I have found that if I add fake closing tags, Prettier
won't indent these lines. And that's what I want.
So if I want for instance <%= myfunction() %>
in my template, I add an extra </%=>
and end up with <%= myfunction() %></%=>
. These extra fake tags won't show in the browser. However, they do appear in View Source, which I find annoying and would like to fix.
I wrote a simple function to remove these fake tags.
*RemoveFakeClosingTags.prg && Should be a function or a method.
Lparameters tcText
m.tcText = Strtran(m.tcText ,'</%>','')
m.tcText = Strtran(m.tcText ,'</%=>','')
m.tcText = Strtran(m.tcText ,'</%:>','')
Return m.tcText
My only problem is that I am not sure where I can "hook" this code into WC.
I would also be very happy if this functionality was implemented in the next version of WC.
Rick, please do me the favor and look into this. I have spent several hours reading your documentation, and I'm pretty sure that some of it simply isn't correct anymore, and needs updating. The same I believe is true for some of your old colorful "slides" which show the "flow" of your framework. Small but very important changes have been made over the years without the slides being updated. And this has "cost" me several hours.
Please take into consideration that English isn't my first language. It's not even my second. So it's very possible that I have missed something in the translation...!
After studying your help files, my understanding of how templates are handled, is that most of the work is done in the wwPageResponse class. So my first idea was to create a subclass of wwPageResponse, and override the Write method. To implement this, I considered to edit wconnect_override.h and define another value for WWC_PAGERESPONSE, pointing to my subclassed version. However, when I searched your source code, I only find one reference to this value, which sets this value to the property cPageResponse. And when I search for this property, I find that it's not used anywhere...
And based on this, I conclude that wwPageResponse is not used at all anymore. Is this correct? And if so, please tell me which class and method I need to override.
I am aware that you may think that I am a kind of stubborn, and that I make a problem of something that's not important at all. And I agree, to some part. However, my reason in this case is twofold. I want to get rid of the "fake" end tags, that's true. But even more important is that I want to learn more about how WC works, and how to make it work "my way".
I don't have an answer for you and we're not changing these tags just so the tooling works. The problem is the editor that can't handle the ASP tags.
+++ Rick ---
I finally got it to work by defining a subclass of wwPageResponse
at the end of my custom process file. I called it myResponse
, and specified it by setting cResponseClass = "myResponse"
early in the class definition for my process class.
If anyone else wants to avoid unwanted indentation when using VS Code and Prettier, and also don't want to see any "fake" ending tags in View Source
, here's my procedure.
At the very end of your xxxProcess.prg
file, add this:
Define class myResponse as WWC_PAGERESPONSE
Function Write(tcText,llNoOutput)
If '</%' $ m.tcText
m.tcText = Strtran(m.tcText ,'</%>','')
m.tcText = Strtran(m.tcText ,'</%=>','')
m.tcText = Strtran(m.tcText ,'</%:>','')
Endif
Dodefault(tcText, llNoOutput)
Enddefine
And make this change in the same xxxProcess.prg
file, soon after DEFINE CLASS xxxProcess AS WWC_PROCESS
:
*** cResponseClass = [WWC_PAGERESPONSE] && Commented out
cResponseClass = "myResponse"
In my custom html.json
snippet library for VS Code, I added these lines at the very end:
"tb-wcmacro1": {
"prefix": "tb-macro1",
"body": "<% $0 %></%>"
},
"tb-wcmacro2": {
"prefix": "tb-macro2",
"body": "<%= $0 %></%=>"
},
"tb-wcmacro3": {
"prefix": "tb-macro3",
"body": "<%: $0 %></%:>"
}
If you already have a custom html.json
file, make sure to add a comma immediately before these snippets. Now, if you type for instance tb-m
, you will see these three macros in a picklist. Select the one you want, and press Tab. If you select the first, you end up with
<% %></%>
and the cursor is placed where you need to fill in your stuff.
You probably should localize this to the ExpandScript()
and ExpandTemplate()
functions, not the entire Response class to avoid the translation if you're not generating ExpandTemplate/Script output. When the file or string is read in - do the translation at that point before it hits the processing. In fact, the better place for this is probably the wwScripting
class which handles the processing. Maybe with a flag that can enable or disable this functionality perhaps globally.
+++ Rick ---
Thank you, that advice was what I was hoping for. The perfect place to inject my code would be the very last "point" in the response process, after all the processing is done and immediately before the data stream is "sent" back to the user's browser.
Huh? If you pass the 'invalid' tags to ExpandScript()
or ExpandTemplate()
they won't work correctly so you have to do that un-encoding before the script/template processing happens. The script tags are removed as part of the wwScripting
processing.
+++ Rick ---
Understood, I'm looking into your code right now. I understand very well what you mean.
Btw., my experience so far is that the 'invalid' tags don't cause any problems at all with WWC, they seem to simply be ignored and passed on.
And please forgive me for having problems with explaining myself properly.
I'm thinking the better way for this would be to make the end tag allowed to be a </%>
That would make the editor happy, and the replacement can then do:
lcText = STRTRAN(lcText,"<%/>", "<%>")
to replace the text which now gives you a valid block to execute.
Or maybe even better:
lcText = STRTRAN(lcText,"% />", "%>")
lcText = STRTRAN(lcText,"%/>", "%>")
To replace:
<%= lcName %/>
<%
* Code here
%/>
+++ Rick ---
That was exactly my first thought also. And that's what I tried my best to explain in my recent enhancement request. However, I realize that if it's only me who wants this, it's not fair to ask you to implement it. So I'll leave that decision to you.
What you just suggested, is that something that I have to do, or will you implement it? If so, I will be patient and wait for the next version.
Not sure yet. I have to play with it to see if this is worthwhile and doesn't impact performance. It shouldn't since what I'm proposing would impact only the templates not the generated data, which should be relatively small compared to potentially very large HTML results to Transform.
Please let me know if you change anything. If not, I will continue to use my own solution unless I see any side effects. I haven't seen any so far, and the speed decrease is ignorable.
I've added this to wwScripting
.
ConvertAspToVfpCode()
First line of code at the top of the method:
IF VARTYPE(lcScriptCode) # "C"
RETURN ""
ENDIF
lcScriptCode = STRTRAN(STRTRAN(lcScriptCode, "%/>","%>"),"% />","%>")
MergeText()
First line of code at the top of the method:
IF ISNULLOREMPTY(tcString)
RETURN ""
ENDIF
tcString = STRTRAN(STRTRAN(tcString, "%/>","%>"),"% />","%>")
This will then support:
<%= version %/>
<%
* code block
%/>
So I installed Prettier extension and checked this out... I really see no difference in behavior. Formatting is still screwed up (ctrl-k-f) as it tries to combine lines. Highlighting is no better for the end tag it still shows as text.
So I'm not sure what issues this is supposed to solve. Using <% />
is also no better - still doesn't align things properly either...
+++ Rick ---
I agree with you that the "perfect" solution would be to use %/>
at the end of these macros, like <% if .t. %/>
. However, unfortunately Prettier adds an extra space, <% if .t. % />
, which looks kind of "ugly".
I have tried many different approaches myself, and ended up with my three different fake ending tags: </%>
, </%=>
and </%:>
. Yes, they are invalid, but the browser seems to ignore them. It's only my "vanity" that makes me want to have them removed when I select View Source. Using them together with the little modifications I mentioned, fulfills my goal.
I don't care if Prettier breaks any of the lines, or about the colors. All I want is that I end up with the left margin being aligned properly. IOW, I want for instance every </div>
in the same column as its matching <div>
.
The code I posted handles the <% />
case, so that's not really a problem. My point is that code formatting will mangle any FoxPro code in between the brackets into a single line (or multiples on arbirtrary breaks) because it thinks it's HTML markup. In short, this will never work properly with an HTML formatter alone - it needs something that understands the tag syntax.
Oddly there isn't an ASP classic syntax highlighter for VS Code - that would likely fix the problem as any code cleanup solution would understand that the code between tags is different than the surrounding HTML.
+++ Rick ---
I confess that your previous message(s) wasn't quite clear to me. Is it so that the two changes you mentioned, will make these three three syntaxes "legal" from WC's point of view? <% if somecondition />
, <%= somefunction() />
and <%: someproperty />
. If so, I'm more than happy.
Or do you meant to say that there isn't really any solution to my problem? If so, I accept that.
Personally I only use "one liners" when I add VFP "stuff" into my HTML, so I don't face the problem with the mangled line breaks. However, I understand that you have to deliver a solution that works in every case.
No the syntax would be:
<%= <expression> %/>
<%
<code block>
%/>
This is valid HTML and will keep the page HTML parser from adjusting the ends tags. We have to keep the %
in there so the parser can find the end tags properly.
+++ Rick ---
Unfortunately Prettier will add an extra space, so for instance <%= somefunction() %/>
becomes <%= somefunction() % />
. So it doesn't solve my initial problem completely.
Perhaps I can write a VS Code macro that will run Prettier, remove the extra space and then save. Since I do this mostly for fun and learning anyway, it could be worth the effort. If I do it, and succeed, I will post the code here.
Until then, I will have to adapt my way of working, something I can live with. Thank you anyway for spending your time on this.
Well the code handles that extra space so that shouldn't be a problem. It converts both %/>
and % />
.
+++ Rick ---