No more CSS and HTML, just JS
ojjs.org
ojjs.org
-------Benefits
1. SEO is not a problem.
Since OJ can be compiled on the server-side, it's comparable to EjS, JADE or other templating languages, which means SEO is not a problem.
2. Current code-size can be ignored in the long run.
This code doesn't have to be sent to the client (since it can run on the server), could possibly be hosted by a CDN and cached across the web, and can probably be tightened up in the future.
3. CSS is still available, but the views know about their css files and are coupled with them
4. True MVC on the front end
OJ gives us the chance to do true MVC in the web frontend, without having a javascript view and an dom view and css styles that are separate, but that work together to make one thing. It seems to me that they're really made for each other - shouldn't they be together at last?
5. Sharing code will be easier
OJ could eventually be supported by a package manager that allows you to include (or install for server-side) js objects for things like youtube videos, but also for tweets etc. Separation of concerns (So your app doesn't just have one huge CSS file, but each view has it's own css, and it's own html & js etc) will also reduce complexity in larger apps.
------Trade offs
1. Yet another framework to learn/use
2. May be slower than what you currently do to render pages
3. If used client side, you may weaken your site's SEO
4. New engineers to your team will likely need to be brought up to speed.
5. (short term) There are likely weird bugs you'll pull your hair out over.
In addition oj has an (optional) server side commandline tool that already supports a Browserify-like approach of building websites that can use Node packages. So if you are looking to make a static page for say GitHub pages, the OJ commandline tool already supports using npm as an OJ package manager.
One last thing: my top priority right now is Express Server integration to finish out the dream of shared Client and Server code in node. This will allow use of npm as packages even more, so if any experts on Express are out there, I'd love to talk to you.
I've been thinking a lot about frameworks along these lines; use js (or something that compiles to js) for the logic, allowing shared code-bases on server and client. One major motivation would be to seamlessly render on server for clients that doesn't support javascript (be they lynx/w3m or some crawler etc). Another would of course be to try and keep things reusable.
I'm not so sure html+css+"interactive/event-handling"-js is a good "compile target", though. I'd much rather see something as close to the output as reasonable -- because there are so many corner-cases with html and css. This is one of the reasons why I like the idea of zope's TAL/METAL templating[M] so much. My interest in TAL is also why I don't think this (general architecture) is going to quite work.
With TAL, you can basically make a mockup that is a template, complete with sample data. But then you need to break up that template to have widgets. And widgets need to be inserted across different areas of the document (think a calendar, where you mouse over events to change an info box. That can be structured, but it is going to cut across a lot of you entire page/app. Even if you don't load content asynchronously). This is done in Plone/Zope using METAL (Macro Expansion for Template Attribute Language).
In fact, the Plone project has essentially given up the idea of using TAL+METAL to theme a site -- it is now (ME)TAL->html+css+js -> page/app "base". Then that base is modified/rewrtitten using diazo[D] (xml transform but with easy support for using css selectors rather than forcing full xpath syntax on a poor dev) - that basically can include new css and js -- but fundamentally can rewrite the entire html-document, splicing in content in sections.
I'm not sure that that is the best way forward either -- but I think that is one of the best ways of writing rich html "documents" -- or systems that revolve around pages. For "pure" apps, I think maybe a full on js approach like ELM[E] is better -- the code is cleaner -- you don't really care about the html, css or even javascript as such -- you focus on the functionality.
As for Ojs, I looked a bit at the examples:
http://ojjs.org/download.html#examples
and one thing struck me -- is there really a reason for the js client and server examples to be different? Couldn't/shouldn't the server side tools be able to deal with the code for client side -- so that you can write once, and then deliver server side or client side from the (exact) same code base?Despite all this, I think it is an interesting project.
[M] http://en.wikipedia.org/wiki/Template_Attribute_Language [E] http://elm-lang.org/ [D] http://docs.diazo.org/en/latest/index.html
That said, I completely agree and hope over time more and more people will embrace the server-side way as it makes downloading and updating plugins really simple. Maybe in time that path should be emphasized more.
<html>
<head>
<title>OJ Example: html shim</title>
<!--Include OJ -->
<script src="oj.min.js" type='text/javascript'>
</script>
<!--Include OJ app/page -->
<script src="example.oj" type='text/javascript'>
</script>
</head>
<body>
<noscript>
<h1>Something went wrong</h1>
<p>So sorry. The server was unable to detect that
your client doesn't support javascript. Please try:
<a href="?force-server-side-rendering=true">magick</a>.
(Maybe that should be a client side redirect, via a meta-tag:)
<meta http-equiv="refresh"
content="1; url=?force-server-side-rendering=true">
</p>
</noscript>
</body>
</html>
Now, example.oj will pull in stuff via require etc, and given a "smart"
server, the same page/app can render client side and server side?[edit: The oj.js script should also probably be able to redirect the client "back" to client side rendering, if it detects js -- so that if google links to url/?server-side-rendring=true -- not all clients from google will be "forced" to do server side rendering.]
Code size can't be ignored because the JS community at large values small modular components, i.e., Sinatra over Rails. Libraries live or die mostly by popularity, so there you go.
The trade-offs you listed are not really significant. We all pick up frameworks and languages almost any year anyway, and the comments about client-side SEO are just way off.
I keep harping on this bit, but that keeps popping up in HN all the time. Again, client-side apps won't hurt your SEO, and there's even services based around it like http://seo4ajax.com
Most people running js webapps are not following google's ajax webcrawling directives or paying seo4ajax to solve the problem for them. It's irresponsible to say that there's no SEO problem with client side rendering.
There are no large caveats here, either follow a tutorial off Google Dev Guides or pay someone like $5 bucks a month to do it.
Nick Denton: "Dip in uniques largely because of drop in Google refers. Pageviews (which are driven more by core audience) less affected." -- http://twitter.com/nicknotned/status/61152134929981440
Nick Denton: "Google does not fully support "hashbang" URLs. So we're eliminating them rather than waiting for Mountain View." -- http://twitter.com/nicknotned/status/61465859079671808
Nick Denton: "Yeah, I'd advise against hashbang urls. Will kill search traffic -- even if you abide by Google protocol." -- http://twitter.com/nicknotned/status/62595141927583745
Not to mention internal crawlers for site-wide search (although you can of course adapt those -- why do it if you don't have to?).
It is possible that some more complex UI elements (say a Calendar) will have to be done in Javascript, but that seems like a worthwhile tradeoff for simplicity, efficiency, and maintainability.
The whole point of HTML and CSS is to be declarative, non-procedural ways of specifying presentation and UX behavior. The rationale is that designers writing CSS rules is safer than developers writing Javascript code -- for those cases where the desired result can be achieved with either approach.
So why turn back the clock and go back to messing with code and debugging it? Unless I am missing something, heavy-weight pages with potential for bugs does not seem like a win.
Don't get me wrong, I like HTML and I'm not trying to disrespect what was arguably the first foray I had with "programming". But if we are intending to make the web into something more along the lines of a massively distributed application runtime, rather than a repository of documents that anyone can access, where does a document markup description language fit into all that? When developing some (kinds of) applications, I feel that HTML only serves as an obstacle, rather than a means of helping me make the app. I feel like I do most of my "real work" in CSS and JavaScript.
Same thing with dynamic languages. You cannot write a Java, Python, or Ruby app and expect it to run on any device. Just doesn't work when you need to also distribute the runtime framework on a per platform basis.
Similarly, you have semi-portable C# and C++ through Mono and Qt that reach pretty much every major platform (the primary limiter is ios being so locked down) but they both need to do ugly repackaging of their entire toolkit runtime and framework that has to somehow jump through hoops to get installed locally whenever you try to install such a program.
But you can expect html, css, and js on everything. And that is why everyone tries to stick completely tangential computing techologies (html is not a widget toolkit) and hope for the best. Because it is the only write once, run everywhere where the run everywhere actually happens, even if your site ends up being double in size for mobile and desktop versions or reactive with tons of overhead in element scaling, plus all the conditionals for old versions of IE, having to import require.js or something to check for feature compatability, etc.
But you can work with that. You can write megabytes of JS to try to weasel around the mess. There is literally nothing you can do to get a python app running on average joes iphone.
I really hope qml can take off in a big way, and become a standard of some sort. It is in my experience the portable ui toolkit for actual applications that is portable and looks native since 5.2, and it even lets you script it in js so you never have to compile anything with a qmlscene binary. And it is designed ground up to have any resource local or networked.
Nowadays, there's a lot that can be done with modern CSS that in the past required Javascript code -- from dynamic menus to 3d effects to responsive web design. This is a good thing.
Code is a breeding ground for bugs (especially dynamic code with callbacks, evals, unusual inheritance model, unconventional scoping rules, etc) in a way that declarative rules are not.
Applications are still, in essence, a type of interactive view hierarchy of document. The web can serve up both types of data: document-based (e.g. Wikipedia) and application-based (e.g. Gmail). Being able to have a core toolchain of three inter-related languages that can communicate with each other that you can use as required should be the final goal. For instance, if you're writing a web application, you could only use CSS/JS, and if you needed to write a very simple blog, you could use all three, or just HTML and CSS.
Having more options never hurt anyone. Better JIT of JavaScript code would break pure JS open, allowing full apps to be written without language fragmentation. Those who will still require stylesheets can use them as they wish. It's a win-win situation on both ends.
an email message is a document too.
An email client is not.
Or another way to say it -- Imagine you can insert a YouTubeVideo as simply as you can insert a div. If that YouTubeVideo component is well tested, then you are actually saving your self time and will make a more robust site.
And then we can have laymen code the templates and styling because it will be so simple.
It will be glorious!
Also just for those who didn't realize, this is the initial release of OJ and was written by just one dude. As people start using it and a people give feedback it is just going to get faster, smaller, and better. Let me assure you perf and filesize are big priorities, as is better Express and Node templating integration.
Congrats on the release, I wish you luck for the rest!
I am however open to new ways of doing things so I will keep an eye on this, but I must admit, that index page looks a lot more daunting to edit than a normal HTML page, especially if you are not familiar with JavaScript.
For me personally, the design principle of "separation of concerns" has always worked well, especially in a team environment. Having a pure designer (on photoshop or illustrator), then an html/css expert for coding pages and finally a programmer for adding dynamic content works out as a nice pipeline for web development. With ojjs, the programmer and html/css person would have blurred lines separating their responsibilities. It is a cool project, but it seems like a step backwards to me. Maybe it's just a step sideways or a better way of doing things for a team consisting entirely of programmers.
But to your question should all CSS be in JS? I'd say no, that wouldn't make sense. Clearly site level CSS should remain in a file and can be just included in a link tag normally.
The CSS being moved into JavaScript would be just that CSS used by the objects. This is how OJ Objects have no dependencies. The CSS for the YouTubeVideo, or Tab control, or the TwitterButton is included in the objects themselves. So definitely imagine still using CSS as you do now, but pulling out only the css needed for the reusable components into OJ Objects.
For structure (the meaning and content of each element), use HTML. For presentation (e.g. colors, fonts, transition appearance), stick to your linked stylesheet. If you need to modify behavior (e.g. what happens on a given event), do that in a Javascript include.
I am a huge fan of AngularJS, because it's essentially following the same separation pattern. It uses references (like ng-model, ng-controller, etc.) to attach elements to associated interactive behavior, but doesn't actually interfere with the structure of the page.
Using JS to insert CSS, DOM nodes, and more JS is becoming pretty standard now. ExtJS and GWT led the way seven years ago, and frameworks need only dumb it down more to gain popular acceptance. I've been on teams that made award winning sites with GWT, but you had a steep learning curve. Perhaps OJ can overcome that.
ExtJS didn't lead shit...there is a reason hardly anyone uses it.
GWT I am not personally familiar with, but if it is at all like ExtJS I want to stay AWAY as much as possible.
One major reason is it's just so freaking large and unruly to do anything simple. It's one of the few frameworks I've used that even after moderate use, I still had to keep the docs open on one screen even during routine development. The error messages weren't very helpful, either.
Just experimenting around it's pretty valid IMO.
That being said, this library does try to solve a problem, it's not useless. In my opinion, it's just not the right tool.. yet.
Now it's possible that the layout of the current browser DOM represents ultimate perfection and we will never improve upon it. However, it is more likely that we will find some way to come up with a better design for the DOM in the future (i.e. new types of nodes, node attributes, member functions, or some sort of entirely new data structure) and these types of frameworks allow us to experiment with new DOM ideas. With oj.js or react.js you could write to this "new DOM" and the library will project changes back to the legacy DOM.
[1]: http://www.w3.org/TR/2013/WD-components-intro-20130606/ [2]: http://www.polymer-project.org/
They also have some repositories for ready to use webcomponents like x-registry [2] or brick [3].
[1]: http://www.x-tags.org/ [2]: http://registry.x-tags.org/ [3]: http://mozilla.github.io/brick/
<ul><li>They</li><li>create</li><li>themselves</li></ul>
OJJS Version - 57 Characters, thousands of lines of js dependencies:
var myList = oj.BulletList('They','create','themselves');
The fact that just writing the html output is the same (and in this case less) amount of characters then the ojjs functions makes me unsure about this. especially considering all the extra dependencies.
My point in bringing up something like the difference in character count (not counting characters in the dependencies) is that just calling the function is already more work than basic html. That immediately is a NO for me.
One could argue maintenance, incompatibilities, bloat, optimization, debugging, and so much more.
To nitpick, to get your HTML, the OJ example could actually be:
> BulletList('They','create','themselves')
So no, it's not more work (41 characters).
I get what you're trying to do, because i did something similar with forms in PHP, but the dependencies and functions are too much... especially for production use.
my advice is i would maybe focus on doing less things more efficiently. Or even better, offering a way like TW Bootstrap does, where you can choose your components and it spits out what you want.
I wouldn't use 95% of the functionality of this code so having thousands of lines of code that i will never use is very unattractive for me when im thinking about optimization, debugging, etc.
ADDITION: And i mean something that compiles your main ojjs js file, BEFORE the plugins. For example: I would never need any of the css functionality in this but it's included in the core. That's what i meant. I'm aware you have the ability to add 'plugins'. My idea of choosing parts was to choose parts within the current 'core' code.
However, it looks like you are investing a lot of time into this and it's not a bad idea, so i applaud that. Just think it needs a little organizing/re-thinking in some aspects. Good luck :)
As for the CSS support it is actually quite elegant. Maybe 100 lines with full support for '&:nested' selectors, and nestable '@media' query support.
One thing that I've been considering is right now 40-50% of the oj.js filesize is support for the Form Elements (TextBox, ListBox, CheckBox,Button) and the "collection" elements (BulletList,NumberList,Table). I'm still considering pulling these out of the core and making them plugins. The issue is they manipulate the basic tags (input,textarea,table,ul,etc) so they seem pretty fundamental. Is that something you would want?
It's not impossible to be an expert graphic designer and web developer, but they are both extremely deep disciplines and people with the dedication, inclination, and aptitude for both are few and far between. Unicorns, etc...
This is fine for one-offs and side projects, but trying to build large project around this seems like an unnecessary extra layer of complexity (not that the current standard isn't complex, it's just relatively entrenched, for better or worse :)
You will know how much it costs to use something like this if you have a project that you've worked on for weeks or months and need to hand it over to another developer. Or actually any other interaction with a third party like a designer or frontender that's used to just juggling around some tags for preference or layout optimisation.
Do you have any other reason why we shouldn't use OJ?
Other folks here have mention the separation of concerns. Is there something that you can say related to that? Loved your summary of benefits and trade-offs, but can you please address MarkHarmon's comments? Thanks.
What we are seeing here is an attempt to solve the same problem, but by doing all the work by using JavaScript. Cool. But not impressed.
Can HTML be the view without css and without js binding for events and updates? Not in a modern app!
Can CSS be the view without HTML/JS? NO!
Can JS alone be the view? Yes, but you'd have a lot of inline css and html - it'd be and a pain in the ass to maintain.
So if you want a single, true View in your MVC, you'd need a view that has all three parts. Other frameworks like backbone try to do something similar - backbone allows you to let your view have a template, but backbone views rely on external css and often attach to dom elements that aren't even in the view's template. So what you have is a view that's only referring to/aware of a few of it's actual dependencies. That seems sloppy if you ask me.
Also, if I had a TweetView that was a backbone view, and I wanted to move it to another person's system - maybe I created an awesome design and called it AwesomeTweet - other people who wanted to consume AwesomeTweet without OJ today would have to include a css file, some html (or a template) and some JS. Each presents a rich opportunity for namespace collisions, and for my bad documentation to make it difficult to import AwesomeTweet as a module. Instead, OJ could allow a simple line like showAwesomeTweet('2131221121'), which would be guaranteed to work everywhere, simply.
Does this explain the "why" better?
Ah, but you are sacrificing uniformity of design there. What if I would like the style of the tweet to be consistent with the overall style of my app? And this style is managed by a separate designer not a programmer?
Modularity works fine for behaviour, because it is better to abstract and encapsulate behaviour. But modularity doesn't necessarily work great for looks and feels.
Here is a JSFiddle I made to demonstrate. This isn't even in the docs yet, so I made this just for you=).
Pagespeed goes into this a bit here: https://developers.google.com/speed/docs/insights/Prioritize...
To me the answer is obvious: we have people who don't understand CSS, who don't understand HTML, who do understand JavaScript (or Java, or Ruby, or Go, or whatever) who want to make web applications but have no interest in learning or understanding the reasons why we do things a certain way.
Frankly it depresses the hell out of me for the next generation of web applications, because it feels like we're taking a technological leap backwards.
It works pretty well. But when you have complex layouts, your JavaScript files can become very complex with many layers of nested object definitions. I use Ext and love it, but personally I think an HTML markup approach to defining UI's is cleaner.
That said, lay all the perf blame on me! I can promise it will get better -- though in my defense this is the first release after all. Literally no one had heard of OJ until yesterday=).
The tool for server side static site generation is available in node npm. You can install it with `npm install -g oj`. Example projects can be found here: https://github.com/ojjs/oj-examples
(sorry, that's the most constructive I can get with this)
Pretty much everyone's had the idea that, since HTML is a structured markup language, you can "simply" represent it in whatever language you're working in. It's great when you're a noob & want to make something ideologically pure.
It just turns into a giant pile of unmanagable shit if you try to extend it out to anything remotely resembling a real world application. Even a simple layout like HN would require an incomprehensible mess of nested objects/s-expressions/functions if you chose to abstract the raw HTML away. This is why everyone that actually develops web applications resorts to templates.
Having proper components is a big win. However, it seems it requires a command line dependency to the build app, which would be nice not to: http://ojjs.org/docs.html#file-types
Check out this JSFiddle to see how the dependences work: http://jsfiddle.net/evanmoran/c3Reb/
(Notice that OJ doesn't need HTML or CSS!)
It removes HTML, CSS and JS from the equation with just one language, Elm, which uses FRP (functional reactive programming) for doing UIs.
For example, it makes sense to have a Javascript class such as "ShoppingListView" that takes care of rendering a shopping list via a template that it references. A component like a shopping list is coarse grained enough to be styled and designed on its own (by designers) and then stuck into a template (by designers) that the Javascript developer can then use and populate in code.
oj just takes us back to the tedious GUI development of Swing style frameworks. It is unfortunate that some people in every generation forget what the previous generation has already learned.
So ShoppingListView would be a powerful object that you could test and reuse. For example in the ojjs.org site I have an object called TryEditor, which does the live compiling examples. Clearly this isn't a plugin people will want (though it is made with the AceEditor plugin, which is pretty darn useful!), but it helped me to abstract it easily so I could use it, well, pretty much everywhere=).
Another way to think of it is imagine you were making Gmail. It would be helpeful to have an object handle EmailView, LabelView, and FriendView. These things are tied to data but wouldn't it be easier to interface with them as an object interface (addEmail, archiveEmail), then with direct DOM manipulation?
IMO you'd get a better reaction if you put a large chunk of your Plugins page on your main page. The "plugins" page better illustrates the purpose and vision of OJJS. The example on the main page is so low level it turns people off.
That being said, I still think the bulk of the "markup" should be in markup and reside as a template for your "plugin" or component to use.
So you have an EmailView component but with an EmailView template file as well. The EmailView is instantiated and manipulated in Javascript but it still has the benefits of markup via its template file.
Concrete example: Template: https://github.com/tantaman/Strut/blob/master/app/bundles/ap... Component: https://github.com/tantaman/Strut/blob/master/app/bundles/ap...
As for separating templating from the View it is a good point. In OJ you can use functions to create templates (or partials) since everything is just code.
I did find the unification of structure (HTML) and code (JS event bindings) quite helpful because this way the code that needs to find the HTML to bind an event is the very same code that created it. This removes the need to have class names / ids just so you can refer across HTML/CSS/JS boundaries.
So think more, what if I could bundle a part of my website into ShoppingCartView, or HeaderBarWithLoginView? It doesn't remove the HTML and CSS it just simplifies how it is created because OJ Objects create themselves, and once created they modify themselves. Clearly to write these objects you will still need to use and know HTML and CSS, but this provides a different way of encapsulating things.
In other words, if you think of this as a way to generate HTML snippets with events binding, then, this might not looked as such crazy idea. Of curse when it aims at building the entire website with, one will wonder why.
Having said that, a suggestion to the author, start using name spaces, i.e. put all plugins under the namespace of .plugins, e.g. plugins.YouTube(), plugins.Ace() instead of just YouTube() and Ace().
There's already a lot of work put into this, it's worth going that extra step and make things look less like the messy days of HTML and Java and Flash a decade ago.
Why not start with some content instead?
Check out this presentation by Nicholas C. Zakas: https://www.youtube.com/watch?v=li4Y0E_x8zE
Please stop the madness.
Interesting. But why would we use this? Or is it just for fun?
Check out this JSFiddle to make Vimeo videos!
I've toyed with my own similar tech to OJ in Javascript before, but couldn't justify the overhead in the client at the time.
But I don't really see why I'd want to do that.
But it reminds me a little bit to perl cgi in the 90's.
print h1('hello world');
I mean, this is great for people fast learning, but will never work against "fronted" people in the average (non top) company.I wish I'm wrong.
But right now. At this point when I'm right now very long to explain, that sentence, has made my day. Up-voted.
Yes, with quotes, it means something like.
Maybe I should really say designers, but it's the same, there are designers who can learn a new syntax in two afternoons, and there are those (in my experience, more) than no.
uiji.js http://aakilfernandes.com/uiji.html
domo.js http://domo-js.com/
As you might imagine I would disagree that JS is the wrong language simply because it _is_ the web. Clearly abstracting JS to other languages can be quite useful (CoffeeScript), but by making your building blocks in JS every developer, library, or framework can use them. They become universal. If OJ can add YouTubeVideos, anyone can. It would be harder to do this if it was written in another language.
*HTML & CSS
I've got to apologize for the harsh tone of the original posting. I have a few friends who are either legally or totally blind, and have had to help them try to find software that is reader-compatible so they can interact with the world around them. So seeing the "everything is dynamic" ability sold as the big reason to use this templating language, and knowing that readers can get confused if there's a lot of weird actions going on with the DOM, made me frustrated that there was yet another tool made that will further alienate these people, and make it harder to use one of the most awesome tools made for communications. Too many people take a path that is essentially "fuck the blind", which is just saddenning.
What it came down to is this behavior leads to a really nice syntax inspired by the excellent coffeekup js templating language (http://coffeekup.org/). The key is you can't really do computation or logic in anything but a function so using functions for nesting elements leads to elegant code. For example you could generate `li` tags inside of a `ul` tag: ul(function(){for loop{ li(...)}}).
That said, you don't have to use the functional notation to use OJ. All the functions and plugins support an _ variant (_YouTubeVideo, _div) that don't emit, and in addition everything in OJ can be written with a list syntax I call OJML. The syntax looks a bit like lisp and is actually what the functions, plugins, and css are all generating: [div, {'class':'my-cls',[YouTubeVideo,'url/to/video']].
There's a fundamental disjunction between today's search crawlers and these kind of dynamic Javascript apps that's just going to become even worse.
If anything, I think libraries like OJ point out the disjunction and therefore encourage discussion of what the future should be. HTML and Javascript have served us admirably, and given the nature of the web one wonders if we will ever get away from these technologies. That said, using one in isolation without the other (i.e. Javascript to generate HTML but not writing HTML) diminishes both as far as the usefulness of the "web" as we used to know it, at least.
I might even go so far as to say that fully dynamic browser apps, without the proper functionality for search engine indexing, are a direct threat to the business model and usefulness of search engines.
https://www.google.com/search?q=uiji.js
Check out the results for the 1st link (aakilfernandes.com/uiji.html) and then check the source code. You'll see that the entire body of the page is written with javascript.
For example, same search on Bing - http://www.bing.com/search?q=uiji.js
References: - https://twitter.com/mattcutts/status/131425949597179904 - http://www.biznology.com/2012/01/no-more-seo-worries-for-dyn...
It should also look like natural speech.