Ok, my question's not as broad as it seems, to summarize 8 months effort on my part:
I create chunks of re-usable, extensible XHTML which degrades gracefully and is all kinds of awesome. Most of my code chunks are provided a Javascript interaction layer, and are styled with CSS. I set to work pulling my code chunks into Dreamweaver as 'Snippets' but they're unintelligent chunks of text. Also, once inserted, my beautiful code chunks get mangled by the non-techies who are the ones actually using Dreamweaver.
Also, because they're unintelligent snippets, I have a line of Javascript which configures the code chunks when initialised - see this post for further detail on my approach. But currently I have to replicate a single code chunk as many times as there are configuration options (so each 'snippet' may only differ from another of the same type by ONE config value). This is incredibly lame, it works, but its lame and time-consuming for me to re-deploy a bunch of snippets and hard for my team to remember all the variations.
So I have a series of requirements, to my mind, as the most likely things to solve in any system I put my chunks into:
The inserted code is not modified at insertion time, by the system
The code to be inserted needs to allow config options
I'd be overjoyed if, once inserted, the only editable parts are text nodes
Copy and pasting these whole objects
A clean interface from which to choose from my range of code chunks
It's a serious list of requirements I presume, much searching led me to Kompoze and its 'Smart widgets' which, according to a random post from 2004, suggests XUL files can be created and extensions can be made which sounds vaguely like what I want. The text editor itself was less prone to destruction, when compared to Dreamweaver.
So yeah, I've chased too many rabbits on this one, keen as for a solution whether Software+extension, or Webapp.
EDIT:
Btw, it did occur to me to investigate a highly customised TinyMCE instance, but I don't know feasible that is, and unless there's some sweet backend available, I'm stuck with local editing of files for now - not even on a web server...
To my mind the best answer to this question will solve most of the above, and provide some general workflow advice alongside the suggestion(s).
I would go with a solution based around the excellent markItUp! editor. It's very simple to extend it to cope with the requirements you have. You can add sophisticated logic, and it's nice and shiny.
I'd probably combine it with Jeditable for the inline node editing, and build the whole thing on top of Django, for ease and convenience. Completely customisable, surprisingly easy to work with, portable and cross-platform, and easy to set-up for off-line use. Oh, and all free and open-source.
What do you think of this approach:
<div class="thing">
<elements... />
<script type="text/javascript">
document.write('<span id="thing' + thingNo + '"></span>')
new Thing().init({ id:'thing'+thingNo; });
thingNo += 1;
</script>
</div>
Of course, you'll have to change Thing().init so that it would initialize the parent (instead of current) node.
Have you considered server-side includes where the directive is either a generated page or a shell command? E.g.:
<!--#include virtual="./activePage.aspx?withParam1=something¶m2=somethingelse" -->
or
<!--#exec cmd="shellCommand -withParams" -->
You can reuse the same page or command, and provide parameters specific to each usage in each XHTML page.
Related
Forgive me if this is a really stupid question, but I haven't found any answers yet - or maybe I don't know the correct thing to ask for.
Given the following files that are part of the same project:
MyProject.html
MyProject.css
MyProject.js
(and a MyProject.py that runs on the server to make things happen)
. . . where all three of these items are related and are actually part of a single project and they need to integrate together.
The "html" part of VS code makes sure the html is correct.
The "css" part of VS code makes sure the css is correct.
the JavaScript part of VS code makes sure the javascript is correct.
However, they may not be correct together as a unified whole - I may have changed something in the javascript that references something in the html that may not yet exist - because I forgot to write it, and I don't discover this until I launch things and watch the web-page go all pear-shaped in ways I've never heard of before.
Is there something that will take all these pieces and say "Hey! You changed the definition of this element here in the Javascript but not in the HTML (or the CSS or whatever)
In other words, not only do I want to know if the individual files are syntactically correct, but do they agree with each other?
If there is a "something" that does this, what is it called?
That tool will never exist and for good reasons, it'd slow the living hell out of your computer when programming and wouldn't fair well as a best practice. Though it's cool, it's cooler to write code effectively and not have a slow code editor. So to that suggestion is write your JavaScript and HTML together hand in hand; split view and you won't ever have an issue. CSS can come into play any time.
Your best option for knowing if code is correct, would be a linter but that won't help you with the issues you face if you're calling elements that don't exist or did you'll want to improve how you code these functions/events.
As requested submitted as an answer for the OP.
I've been arguing for some time against embedding server-side tags in JavaScript code, but was put on the spot today by a developer who seemed unconvinced
The code in question was a legacy ASP application, although this is largely unimportant as it could equally apply to ASP.NET or PHP (for example).
The example in question revolved around the use of a constant that they had defined in ServerSide code.
'VB
Const MY_CONST: MY_CONST = 1
If sMyVbVar = MY_CONST Then
'Do Something
End If
//JavaScript
if (sMyJsVar === "<%= MY_CONST%>"){
//DoSomething
}
My standard arguments against this are:
Script injection: The server-side tag could include code that can break the JavaScript code
Unit testing. Harder to isolate units of code for testing
Code Separation : We should keep web page technologies apart as much as possible.
The reason for doing this was so that the developer did not have to define the constant in two places. They reasoned that as it was a value that they controlled, that it wasn't subject to script injection. This reduced my justification for (1) to "We're trying to keep the standards simple, and defining exception cases would confuse people"
The unit testing and code separation arguments did not hold water either, as the page itself was a horrible amalgam of HTML, JavaScript, ASP.NET, CSS, XML....you name it, it was there. No code that was every going to be included in this page could possibly be unit tested.
So I found myself feeling like a bit of a pedant insisting that the code was changed, given the circumstances.
Are there any further arguments that might support my reasoning, or am I, in fact being a bit pedantic in this insistence?
Script injection: The server-side tag could include code that can break the JavaScript code
So write the code properly and make sure that values are correctly escaped when introduced into the JavaScript context. If your framework doesn't include a JavaScript "quoter" tool (hint: the JSON support is probably all you need), write one.
Unit testing. Harder to isolate units of code for testing
This is a good point, but if it's necessary for the server to drop things into the page for code to use, then it's necessary. I mean, there are times when this simply has to be done. A good way to do it is for the page to contain some sort of minimal block of data. Thus the server-munged JavaScript on the page really isn't "code" to be tested, it's just data. The real client code included from .js files can find the data and use it.
Thus, the page may contain:
<script>
(function(window) {
window['pageData'] = {
companyName: '<%= company.name %>',
// etc
};
})(this);
</script>
Now your nicely-encapsulated pure JavaScript code in ".js" files just has to check for window.pageData, and it's good to go.
Code Separation : We should keep web page technologies apart as much as possible.
Agreed, but it's simply a fact that sometimes server-side data needs to drive client-side behavior. To create hidden DOM nodes solely for the purpose of storing data and satisfying your rules is itself a pretty ugly practice.
Coding rules and aesthetics are Good Things. However, one should be pragmatic and take everything in perspective. It's important to remember that the context of such rules is not always a Perfect Divine Creation, and in the case of HTML, CSS, and JavaScript I think that fact is glaringly clear. In such an imperfect environment, hard-line rules can force you into unnecessary work and code that's actually harder to maintain.
edit — oh here's something else I just thought of; sort-of a compromise. A "trick" popularized (in part) by the jQuery gang with their "micro template" facility (apologies to the web genius who actually hit upon this first) is to use <script> tags that are sort-of "neutered":
<script id='pageData' type='text/plain'>
{
'companyName': '<%= company.name %>',
'accountType': '<%= user.primaryAccount.type %>',
// etc
}
</script>
Now the browser itself will not even execute that script - the "type" attribute isn't something it understands as being code, so it just ignores it. However, browsers do make the content of such scripts available, so your code can find the script by "id" value and then, via some safe JSON library or a native browser API if available, parse the notation and extract what it needs. The values still have to be properly quoted etc, but you're somewhat safer from XSS holes because it's being parsed as JSON and not as "live" full-blown JavaScript.
The reason for doing this was so that the developer did not have to define the constant in two places.
To me, this is a better argument than any argument you can make against it. It is the DRY principle. And it greatly enhances code maintainability.
Every style guide/rule taken to extreme leads to an anti-pattern. In this case your insistence of separation of technology breaks the DRY principle and can potentially make code harder to maintain. Even DRY itself if taken to extreme can lead to an anti-pattern: softcoding.
Code maintainability is a fine balance. Style guides are there to help maintain that balance. But you have to know when those very guides help and when they themselves become a problem.
Note that in the example you have given the code would not break syntax hilighting or parsing (even stackoverflow hilights it correctly) so the IDE argument would not work since the IDE can still parse that code correctly.
it simply gets unreadable. You have to take a closer look to divide the different languages. If JavaScript and the mixed-in language use the same variable names, things are getting even worse. This is especially hard for people that have to look at others people code.
Many IDEs have problems with syntax highlighting of heavily mixed documents, which can lead to the loss of Auto-Completion, proper Syntax Highlighting and so on.
It makes the code less re-usable. Think of a JavaScript function that does a common task, like echoing an array of things. If you separate the JavaScript-logic from the data it's iterating over, you can use the same function all over your application, and changes to this function have to be done only once. If the data it's iterating over is mixed with the JavaScript output loop you probably end up repeating the JavaScript code just because the mixed in language has an additional if-statement before each loop.
When I first started with Javascript, I usually just put whatever I needed into functions and called them when I needed them. That was then.
Now, as I am building more and more complex web applications with Javascript; taking advantage of its more responsive user interaction, I am realizing that I need to make my code more readable - not only by me, but anyone who replaces me. Besides that, I would like the reduce the moments of 'what the heck, why did I do this' when I read my own code months later (yes, I am being honest here, I do have what the heck was I thinking moments myself, although I try to avoid such cases)
A couple weeks ago, I got into Joose, and so far, it has been good, but I am wondering what the rest do to make their chunk their codes into meaningful segments and readable by the next programmer.
Besides making it readable, what are your steps in making your HTML separated from your code logic? Say you need to create dynamic table rows with data. Do you include that in your Javascript code, appending the td element to the string or do you do anything else. I am looking for real world solutions and ideas, not some theoretical ideas posed by some expert.
So, in case you didnt't understand the above, do you use OOP practices. If you don't what do you use?
For really JS-heavy applications, you should try to mimic Java.
Have as little JS in your HTML as possible (preferably - just the call to the bootstrap function)
Break the code into logical units, keep them all in separate files
Use a script to concatenate/minify the files into a single bundle which you will serve as part of your app
Use JS namespaces to avoid cluttering up the global namespace:
var myapp = {};
myapp.FirstClass = function() { ... };
myapp.FirstClass.prototype.method = function() { ... };
myapp.SecondClass = function() { ... };
Using all these techniques together will yield a very manageable project, even if you are not using any frameworks.
I use unobtrusive javascript, so, outside of the script tags I don't keep any javascript in the html.
The two are completely separated.
A javascript function will start when the DOM tree is completed, which will go through the html and add the javascript events, and whatever else needs to be changed.
In order to organize, I tend to have some javascript files that are named similar to the html pages that they use, and then for common functions I tend to group them by what they do, and pick a name that explains that.
So, for example, if I have UI functions then I may call them: myapp_ui_functions.js
I try to put the name of the application in the filename, unless there is some javascript that is common to several projects, such as strings.js.
I have (usually) one file that contains a bunch of functions and that's it. That is included in every page that uses Javascript. In the pages themselves, I'll make the calls to the functions like:
$(function() {
$("#delete").click(delete_user);
$("#new").click(new_user);
});
where delete_user() and new_user() are defined in the external file.
I too use unobtrusive Javascript, which for me means jQuery (there are other libraries that are unobtrusive).
You don't want a separate file for each page. That just means more unnecessary external HTTP requests. With one file—assuming you've cached it effectively—it'll be downloaded once and that's it (until it changes).
If I have a large amount of Javascript or the site is effectively split into multiple areas then I may split the Javascript but that's not often the case.
Also, in terms of my source code, I may have multiple JS files but I'll often end up combining them into one download for the client (to reduce HTTP requests).
More at Multiple javascript/css files: best practices? and Supercharging Javascript in PHP.
I've been rewriting a lot of my reusable code as jQuery plugins. I moved to jQuery from Prototype when I started doing ASP.NET MVC. Overtime I've migrated a lot my reusable code, or at least the ideas, from Prototype-based OO to jQuery-style plugins. Most of these are stored in their own JS files (mainly intranet apps so page load speed is pretty high anyway despite the extra requests). I suppose I could add a build step that coalesces these if I needed to.
I've also settled on a MasterPage approach that uses a ContentPlaceHolder for scripts that is right before the closing body tag. The standard jQuery/jQuery UI loads, and any other common JS goes right before the script placeholder in the MasterPage. I have tiny bit of JS at the top of the MasterPage that defines an array that holds any functions that partial views need to run on page load. These functions are run from the base document.ready() function in the MasterPage.
All of my JS is completely separate from my mark up. Some JS may exist in partial views -- these are encapsulated when the partial may be included more than once to make it specific to that instance of the view -- but generally not. Typically only included in the placeholders so that it's loaded at the bottom of the page.
Also, if you want to go OO heavy, check out mochikit: http://www.mochikit.com/
I find that developing your javascript using OO methodology is the way to go if you want it to be clean, readable and even somewhat secure. I posted the following question
Cleanest format for writing javascript objects
And got some fantastic responses on how to write my javascript code well. If you follow these basic principles you can use almost any library, such as yui, jquery and prototype, with ease.
https://urbantastic-blog.tumblr.com/post/81336210/tech-tuesday-the-fiddly-bits/amp
Heath from Urbantastic writes about his HTML generation system:
All the HTML in Urbantastic is completely static. All dynamic data is sent via AJAX in JSON format and then combined with the HTML using Javascript. Put another way, the server software for Urbantastic produces and consumes JSON exclusively. HTML, CSS, Javascript, and images are all sent via a different service (a vanilla Nginx server).
I think this is an interesting model as it separates presentation from data physically. I am not an expert in architecture but it seems like there would be a jump in efficiency and stability.
However, the following concerns me:
[subjective] Clojure is extremely powerful; Javascript is not. Writing all the content generation on a language created for another goals will create some pain (imagine writing Javascript-type code in CSS). Unless he has a macro-system for generating Javascript, Heath is probably up to constant switching between JavaScript and Clojure. He'll also have a lot of JS code; probably a lot more than Clojure. That might not be good in terms of power, rapid development, succinctness and all the things we are looking at when switching to LISP-based langauges.
[performance] I am not sure on this but rendering everything on user's machine might lag.
[accessibility] If you have JS disabled you can't use site at all.
[accessibility#2] i suspect that a lot of dynamic data filling with JavaScript will create cross-browser issues.
Can anyone comment? I'd be interested in reading your opinions on this type of architecture.
References:
Link to discussion on HN.
Link to discussion on /r/programming.
"All the HTML in Urbantastic is completely static. All dynamic data is sent via AJAX in JSON format and then combined with the HTML using Javascript."
I think that's the standard model of an RIA. The emphasis word seems to be 'All' here. Cause in many websites a lot of the dynamic content is still not obtained through Ajax, only key features are.
I don't think the rendering issues would be a major bottleneck if you don't have a huge webpage with a lot of elements.
JS accessibility is indeed a problem. But then, users who want to experience AJAX must have JS enabled. Have you done a survey on how many of YOUR users don't have it enabled?
The advantage is, you can serve 99% (by weight) of the content through CDN (like Akamai) or even put it on external storage (eg. S3). Serving only the JSON it's almost impossible for a site to get slashdoted.
When AJAX began to hit it big, late 2005 I wrote a client-side template engine and basically turned my blogger template into a fully fledged AJAX experience.
The thing is, that template stuff, it was really easy to implement and it eliminated a lot of the grunt work.
Here's how it's was done.
<div id="blogger-post-template">
<h1><span id="blogger-post-header"/></h1>
<p><span id="blogger-post-body"/><p>
<div>
And then in JavaScript:
var response = // <- AJAX response
var container = document.getElementById("blogger-post-template");
if (!template) { // template context
template = container.cloneNode(true); // deep clone
}
// clear container
while(container.firstChild)
container.removeChild(template.firstChild);
container.appendChild(instantiate(template, response));
The instantiate function makes a deep clone of the template then searches the clone for identifiers to replace with data found in the response. The end result is a populated DOM tree which was originally defined in HTML. If I had more than one result I just looped through the above code.
My project seems to be getting bigger and bigger and some of my classes are thousands of lines long. It's too hard to search through them every time I want to make changes.
I find JavaScript is not as easy to lay out cleanly as some other programming languages. So when the classes get to be a few thousand lines, I have troubles reading it.
I've tried splitting it into multiple files, but then you're breaking classes apart, which doesn't seem right. For example, if every method in a class uses a global variable, you would only be able to find the global variable in one of the files for that class.
Also, if I want to use the JavaScript code from 100 different .js files, I end up with something like this...
<script type="text/javascript" src="Scripts/classes/Node.js"></script>
<script type="text/javascript" src="Scripts/classes/Queue.js"></script>
<script type="text/javascript" src="Scripts/classes/DblyLinkedList.js"></script>
.... 97 more lines like this
Although, I figured there may be something where I can do...
<script type="text/javascript" src="Scripts/.../*.js"></script>
or something similar... is that right?
Anyone have any tips on managing code as it reaches its extremes?
Tips on cleaning up JavaScript code would also be helpful.
Breaking up JS into separate files has some major drawbacks, chiefly that you're forcing web browsers to make a separate request for each file.
Have you taken a look at leaving all of your files separated out, but making a single-file "bundle" for each project containing only the necessary files? This can be automated via a script.
This SitePoint article might help you get started: http://www.sitepoint.com/blogs/2007/04/10/faster-page-loads-bundle-your-css-and-javascript/
(a) keep your classes shorter [even
though that will mean yet more
files],
(b) keep them "full-text
indexed" for speed of search and
operation (not aware of any IDE
specifically supporting Javascript
this way, but strong editors like
Emacs, Vim, Eclipse, or TextMate sure
do),
(c) group them up hierarchically
so your pages can have just a few
<script> tags for "upper layer"
scripts each of which just pulls in
several of the "lower layer" ones.
Oh, and, of course, religiously keep everything under a good change control system (SVN, Mercurial, or the like), otherwise your life will be surely very very miserable:-(.
You might want to group related classes together into packages, where each package is a single file. Check out YSlow for best practices on performance.
Well, a good editor is always usefull, as it will give you shortcuts to all your functions defined in the files.
Second, make sure you're not looking at a wall of code. Indentation, spaces and newlines are a good help.
Be extremely strict in your indentation. 2 spaces is 2 spaces, always(or whatever amount you use)
if you put your { under a declaration, then always put it there, without exception)
Clear rules about how you want your text aligned will help a lot.
And I don't know about that last thing... I'm not sure browsers can work with that kind of wildcard.
<script type="text/javascript" src="Scripts/.../*.js"></script>
will not work, and besides, you end up with an interesting problem when splitting up dependent files, as you can't guarantee they will all be downloaded in the order you expected.
Unfortunately, your best bet is really a good IDE that can produce an outline for easy navigation. I use Eclipse with Spket and/or Aptana, but whatever makes it easier to manage is what you're looking for.
edit: one more quick note about splitting js into multiple files. Avoid it where possible. Each separate file means a separate http request. Reducing the number of requests required can make a massive difference in site performance.
AvatarKava's advice is sound. Work in separate files and concatenate them at build time. However, I would also recommend you take a look at your class structure. A class "thousands of lines long" doesn't sound too healthy. Are you sure you classes aren't taking on too much responsibility? Are there not tasks that can be shipped out to other single responsibility classes? This would help improve the clarity in your code far more than cunning ways of splitting files.
Same advice applies to most languages...
Avoid globals wherever possible. You can often get the desired behavior by wrapping a static variable, or using objects.
if (foo == undefined)
var foo
Use naming conventions where possible so you can track things down just by reading the variable or function names. Either that or get good with grep, or get an IDE with intellisense.
Split things into directories. Having 100 files in a directory called "classes" is not helpful. As an example, you may have a collections directory for queues, lists, trees, etc. If you've got a lot you may even have a tree subdir, or a list subdir, etc.
You can then also create a global include for that directory... simply a file called collections.js that includes all of the files in that directory. Of course you have to be careful about splitting things up well, since you don't want to be including files you'll never use.