Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New homepage website #1827

Open
brianmhunt opened this issue Jul 12, 2015 · 51 comments
Open

New homepage website #1827

brianmhunt opened this issue Jul 12, 2015 · 51 comments
Milestone

Comments

@brianmhunt
Copy link
Member

Hi everyone,

I am just writing to let everyone know that I have started a new alpha/beta web-site with the hopes that it will replace the current one at knockoutjs.com.

You can check it out at https://brianmhunt.github.io/knockout

It will hopefully include at least the following features:

  • single page app
  • manifest cache (for offline reading)
  • live examples that are editable and exportable to jsFiddle & CodePen
  • searchable plugins list
  • responsive / mobile friendly
  • reorganized documentation and main links
  • show / access historical versions of the documentation (including access the legacy site)

Here's what needs to be done (and I could definitely use some help):

  • convert all the examples to “live” and make sure they work
  • test with multiple browsers
  • styling – colours, graphics (nothing bitmap – just svg, or canvas) etc.
  • enable "inline documentation” of the API
  • write up the structure for the new documentation and examples, to make it accessible for other documentation providers (e.g. Dash)
  • add any missing plugins

In the future, to make this work, here's what has to change in the main site:

  1. We can now start adding inline documentation to the source code, though we need to pick the right set of parameters;
  2. The markdown documentation and example files should go into the main branch -- and change with the version

Cheers all.

@sumitkm
Copy link

sumitkm commented Jul 12, 2015

Super awesome 👍 ! Thanks for initiating the effort. The current site is highly functional and one of the reasons why I love KO so much is because the documentation is there on the tap for all the important bits of the library. However, the current site is anything but exhaustive with respect to what KO can do.
I am more than happy to put some skin in to help with the conversion process and bring out 'undocumented goodies' that is currently a SO question or @rniemeyer post away :-).

@ramitayba
Copy link

It's seem great.
What you've used for routing?

@brianmhunt
Copy link
Member Author

@sumitkm – awesome :) It would certainly help if you posted a list of SO questions that you think out to be in the docs.

@ramitayba Forgive my ignorance – what do you mean by "routing"? 😁

@ramitayba
Copy link

URL routing 😄

@brianmhunt
Copy link
Member Author

@ramitayba – the only url changes are to the hash component of the location. In particular ...

The $root.body(), which is the id of the template for the main part of the page, changes with anchor clicks, which also updates/coincides with the document location hash.

So nothing special. 😁

@simonmurdock
Copy link

The only thing I noticed that is a bit annoying is that on this page - http://brianmhunt.github.io/knockout/computed-dependency-tracking.md#animated the side-by-side view becomes a little cluttered. I'd opt for a one above the other approach.

Could we change this particular tutorial to using CSS3 transitions? I'd be happy to modify and feed back with the appropriate changes if you like? - Assuming it doesn't make it needlessly complex

@mbest
Copy link
Member

mbest commented Jul 13, 2015

@brianmhunt - Great work to start this. When I first clicked the URL, I got an endless loading message. I had to reload the page.

@brianmhunt
Copy link
Member Author

@simonmurdock Thanks – the side-by-side should now only happen when the page is extra-wide (>1280px). Let's see how cluttered that feels. Please by all means feel free to add a CSS3 transition example. Live examples are super-easy now – they follow yaml format like this (feel free to post back with an example in this format):

    ```example
    html: |-
       <a href='#' data-bind='...'></a>
    javascript: |-
       var myViewModel = {}
    ```

@mbest – thanks. That's strange about the loading message. What browser were you using?

@AdamWillden
Copy link
Contributor

@brianmhunt I had the same on first load using Chrome 43.0.2357.132

@AdamWillden
Copy link
Contributor

In fact @brianmhunt I seem to get the same religiously every other load when dev tools is open (caching is disabled). Makes no sense...

@brianmhunt
Copy link
Member Author

@AdamWillden If something goes wrong it should print an error message now ...so we can hopefully tell what's happening from that. Cheers

@AdamWillden
Copy link
Contributor

@brianmhunt there are no messages at all when it goes wrong other than two objects:

API.js:33 Object {type: "function", name: "vtest", source: "test.js", line: 1, vars: Object}
API.js:33 T Object {type: "var", name: "y", source: "x.js", line: 1, vars: Object}

Whereas when it works I get lots of messages as follows with the two objects later down the log:

brianmhunt.github.io/:1 Creating Application Cache with manifest http://brianmhunt.github.io/knockout/ko.appcache
brianmhunt.github.io/:1 Application Cache Checking event
brianmhunt.github.io/:1 Application Cache Downloading event
brianmhunt.github.io/:1 Application Cache Progress event (0 of 19) http://brianmhunt.github.io/knockout/index.html
brianmhunt.github.io/:1 Application Cache Progress event (1 of 19) http://brianmhunt.github.io/knockout/favicon.ico
brianmhunt.github.io/:1 Application Cache Progress event (2 of 19) http://brianmhunt.github.io/knockout/build/templates.html
brianmhunt.github.io/:1 Application Cache Progress event (3 of 19) http://brianmhunt.github.io/knockout/build/markdown.html
brianmhunt.github.io/:1 Application Cache Progress event (4 of 19) http://brianmhunt.github.io/knockout/build/styles.css
brianmhunt.github.io/:1 Application Cache Progress event (5 of 19) http://brianmhunt.github.io/knockout/build/examples.json
brianmhunt.github.io/:1 Application Cache Progress event (6 of 19) http://brianmhunt.github.io/knockout/images/logo.svg
brianmhunt.github.io/:1 Application Cache Progress event (7 of 19) http://brianmhunt.github.io/knockout/build/app.js
brianmhunt.github.io/:1 Application Cache Progress event (8 of 19) http://brianmhunt.github.io/knockout/build/plugins.json
brianmhunt.github.io/:1 Application Cache Progress event (9 of 19) http://brianmhunt.github.io/knockout/images/hourglass.gif
brianmhunt.github.io/:1 Application Cache Progress event (10 of 19) http://brianmhunt.github.io/knockout/fonts/Cherry_Swash.woff
brianmhunt.github.io/:1 Application Cache Progress event (11 of 19) http://brianmhunt.github.io/knockout/fonts/Lato_400italic.woff
brianmhunt.github.io/:1 Application Cache Progress event (12 of 19) http://brianmhunt.github.io/knockout/fonts/Lato_400.woff
brianmhunt.github.io/:1 Application Cache Progress event (13 of 19) http://brianmhunt.github.io/knockout/fonts/Lato_700.woff
brianmhunt.github.io/:1 Application Cache Progress event (14 of 19) http://brianmhunt.github.io/knockout/fonts/fontawesome-webfont.woff
brianmhunt.github.io/:1 Application Cache Progress event (15 of 19) http://brianmhunt.github.io/knockout/fonts/fontawesome-webfont.woff2
brianmhunt.github.io/:1 Application Cache Progress event (16 of 19) http://brianmhunt.github.io/knockout/worker-javascript.js
brianmhunt.github.io/:1 Application Cache Progress event (17 of 19) http://brianmhunt.github.io/knockout/worker-html.js
brianmhunt.github.io/:1 Application Cache Progress event (18 of 19) http://brianmhunt.github.io/knockout/build/libs.js
brianmhunt.github.io/:1 Application Cache Progress event (19 of 19) 
brianmhunt.github.io/:1 Application Cache Cached event
API.js:33 T Object {type: "function", name: "vtest", source: "test.js", line: 1, vars: Object}
API.js:33 T Object {type: "var", name: "y", source: "x.js", line: 1, vars: Object}

@AdamWillden
Copy link
Contributor

worker-javascript.js and worker-html.js are not even requested when it goes wrong if that helps.

@brianmhunt
Copy link
Member Author

Thanks @AdamWillden – I've updated the cache load mechanism, and also set up some debugging messages during the load. Grateful if you could let me know what you see.

@mbest
Copy link
Member

mbest commented Jul 14, 2015

@brianmhunt, Why did you go with a SPA design?

@brianmhunt
Copy link
Member Author

@mbest A few reasons, including:

  1. Performance – < 500ms load time for the entire website once cached; < 50ms page-change time
  2. Accessibility – offline access to the entire site without Internet access
  3. Dynamic – searching, filtering, sorting, etc., are all simplified if the data is loaded from JSON
  4. Demonstration – Some neat aspects of KO can be seen from this site, and SPA appears to be a growing trend with uses in several niches so it seemed a neat opportunity to show an interesting, valuable, and possibly popular technique. :)
  5. 100% Knockout - the only templating library involved is client-side KO

The main drawback I can think of is the SEO url mapping, which I have not yet implemented.

The limited space of the cache is a concern, namely the website cache can be at most around 5MB for most browsers. The two areas where space may go over are:

  1. Plugins – if the list of plugins grows into the hundreds or thousands it may be a lot of space;
  2. Historical versions of the documentation

The way I figured we can get around this is to cache only the latest version of the documentation for offline access, and if necessary segregate the plugins by e.g. the number of stars i.e. include in the cache those plugins that have more than 1 star, but the others accessible only with network access.

Right now the site is 2.4MB, but 400KB of that is fonts, and 1.2MB is unminified libraries. So there is a lot of space to play with for the moment.

The space constraint struck me as worthwhile trade-off for the benefits.

Did any other concerns come to mind?

@AdamWillden
Copy link
Contributor

@brianmhunt works great now for me.

@IanYates
Copy link

Looks nice. Page fails to load in IE 11 unfortunately.

capture

One thing that's both great and unfortunate about the SPA design is that it requires a modern browser. It's awesome in that it shows KO is a library that works with modern techniques. The problem is that it may, to the uninitiated, cause the incorrect belief that KO doesn't support older browsers whereas it's one of the few libraries that considers that support important.

I don't have access to any old browsers (yay for me) but it'd be good to really emphasise to someone who lands upon the page that Legacy browsers are really welcome and they can access the documentation via another site.

Going forward though I suppose that means two sites to maintain unless there's a nice way of turning the SPA data into something that could be rendered server-side, not require local caching or not rely on newer layout tricks as much. There's no perfect answer here :(

@brigand
Copy link

brigand commented Jul 14, 2015

I have some thoughts on this, in response to concerns voiced here and the current implementation. This should be read as casual suggestions based on my experience in developing single page applications in Knockout, Angular, React, and jQuery. Some of this I don't have much experience with.

High level requirements:

  • html with content must be returned for bots, noscript, and browsers that don't support some or all of the code used here, including real functional <a href>s
    • also improves support for screen readers
    • older IE versions get the search engine/noscript version
  • offline access
  • fast navigation
  • no user experience/design compromises by the other requirements

Architecture:

  • prerender pages to static files
  • unrestricted offline caching of data (not in appcache)
    • user settings/state (if applicable)
  • appcache for assets
  • discoverable json content manifest
    • similar to GET / in hypermedia
    • urls are computed from the manifest
      • this makes e.g. without duplicating files

Implementation:

  • jsdom for prerendering (also see Prerendering Strategy below)
    • pros: compatible with knockout, fast enough, w3c compliant dom and allows use of a recent v8 version
    • cons: depends on io.js
  • data caching via IndexedDB, specifically using mozilla/localForage
    • pros: significantly more storage than will ever be required, has fallback options but with limited memory
    • cons: prompts user for permissions
  • code bundling via webpack
    • pros:
    • allows conditional build changes for server/client and dev/prod
    • allows dependencies on files and strategies for how they're included (string literal, url, injected stylesheet)
    • single script without manually specifying concat order or relying on global variables
    • can produce AMD if desired without config change
    • can shim bower dependencies
    • allows trivial code sharing between the build code and client
    • allows injection of constants e.g. DEV to allow better minification
    • modules
    • works for both browser and node.js
    • transforms can be easily enabled/disabled, e.g. es6->es3 takes 10 seconds to enable
    • cons:
    • people may be unfamiliar with it
    • nontrivial to set up (I can help with this)
  • content manifest
    • includes knockout version metadata
    • includes where to find the content files, downloads, cdn files, etc.
    • includes where to find the plugin list
  • content files
    • includes full or partial data needed to present the documentation
    • used for both pre rendering and client side

Prerendering Strategy

The strategy is roughly:

  • default: show content
  • if js support detected: hide content, load content data and scripts
    • if load success: replace content with knockout html and run scripts
    • if load failure: unhide content
  • else: do nothing

prerendering

You'll note that some of the content is conditional on whether it's the server or client version. This is most easily accomplished by having webpack inject true/false into __IS_CLIENT__ and __IS_SERVER__, and making all views inherit from a base class which does this.__IS_CLIENT__ = __IS_CLIENT__ so that templates have access to it.


Most of this can be done incrementally if ever, but yes/no to webpack and yes/no to prerendering affect everything else.

I hope this helps in some way.

@brianmhunt
Copy link
Member Author

@IanYates Thanks for the feedback. I have no way to test IE at the moment, so I may have to rely on others to debug it. :( But it'll get there, I'm sure!

@brigand Thanks for the very detailed thoughts – very helpful. This is very much along the lines of what I was thinking, too. It seems SPA still definitely needs to coincide with multi-page fallback, for broader audiences and SEO.

@IanYates
Copy link

@brianmhunt - Use this: https://remote.modern.ie/. You get free access to an instance of IE on iOS, Android, Mac or Windows. It reads like it's IE on Windows 10, which it is, but it's not the Edge browser so it's more like IE 11.1 :)

@brigand - nice overview :)

If this flavour of docs is adopted then they'd also serve as a model of how to structure a large-ish public-facing KO SPA taking advantage of client-side caching, etc. This is a good thing in itself.

@brianmhunt
Copy link
Member Author

@IanYates Thanks for the tip on remote.modern.ie. I signed up but have not received the email that'll let me get started. Will keep at it.

The system now has a hard link fallback if the single-page app does not work. All the links are now to /a/*.html, and they exist on github and are rendered by the client side. All in ten lines of gulp.

Also, to improve SEO I've added a robots.txt and generation of a sitemap.xml.

@mbest
Copy link
Member

mbest commented Jul 14, 2015

I noticed that after clicking a link, going back doesn't restore the scroll position. I think it's because of the code at https://github.com/brianmhunt/knockout/blob/gh-pages/src/events.js#L43. I think if you swap the $root.open and history.pushState lines, it will work properly.

@mbest
Copy link
Member

mbest commented Jul 14, 2015

@brianmhunt, I think there should be a way for the user to select the static pages or SPA version, maybe with a cookie. Also the new URL method is much better and should allow for anchor links, like the current documentation supports (see #1763 also).

@brianmhunt
Copy link
Member Author

Thanks @mbest – I reversed the order of $root and pushState; let me know if the issue persists. This problem can be notoriously finicky and was browser-dependent. (One reliable option is to debouncably poll the scroll position on the scroll change event and save it with the state.)

There is now an option in the bottom-right of every page that, for lack of creativity, I've called "no single page", and as it suggests checking it disables the single page navigation and stores the preference in localStorage. Out of curiosity, in what scenarios would one with a browser that supports SPA prefer multi-page alternative?

Incidentally, I have written a small project (called opine.js) that'll allow us to make inline documentation of the code and will export files & lines & urls linking to the source. That's coming later, but it's pretty nifty.

@mbest
Copy link
Member

mbest commented Jul 14, 2015

I reversed the order of $root and pushState; let me know if the issue persists.

It's working well now.

@SteveSanderson
Copy link
Contributor

This is so cool! Great stuff @brianmhunt! The project's website has been looking a bit dated and has had some UX problems for a while, so it's excellent to see this new one emerging. It's particularly great to have the "plugins" database integrated into the site.

Further thoughts:

  • SEO/indexability: This is super-important since one of the key uses for the site is to be able to search Google/etc for a particular KO API and get right to the relevant bit of the docs. It sounds like you've already made this work - is that right? I can see the hyperlinks go to real URLs. Is there any way to verify that Google is going to be able to index the fully-rendered content, or are you saying the pages are prerendered via some Gulp taslk?
  • Offline support: Although it's cool that you've been able to make this work, I wouldn't say it's ever come up as a requirement either for me or anyone I've spoken to. There may be a tiny number of people who would benefit, so it's great to have it if there are no drawbacks, but if it complicates anything (or introduces risks - I've had trouble with it in the past (example pitfalls)) I'd not compromise on other things to have it.
  • Visual design: Does anyone know of any web designers or web design companies that might be a good bet? I'd be willing to put in some cash for a couple of days of their time to get a slick and modern look - I guess we'd just need a template or mockup to work towards.

@brianmhunt
Copy link
Member Author

Thanks @SteveSanderson ...

  • SEO – Most pages are both pre-rendered, and rendered on the fly for the single-page app. As well we generate a sitemap.xml. The only pages not pre-rendered (and so not SEO-friendly) are the documentation list, plugins list, and API (basically the pages with lists, accessed from the top-bar), which I'll have to think about to sort out.
  • Offline – Agreed. Offline access is just a bonus of the design, but I've no problem sacrificing it if we run into issues.
  • Visuals – Great idea. I was thinking of adding a Sponsors page, and the prospect of being put on that may be enticing to some. Are there any pages out there that you (or @rniemeyer or @mbest) find particularly striking?

In the meantime, maybe we can set it up as beta.knockoutjs.com (or some such) – I've already set up the CNAME in the repo, so it's just the DNS record now – should be, I'd guess, brianmhunt.github.io. When the time is right perhaps we can put a link/bulletin on the main site about it.

@webketje
Copy link

Quick design feedback:
++ API/ plugins view (remind me much of cdnjs.com)
++ documentation page
-- not sure about stylized font in the navigation
-- don't like tilted headings, makes it look too playful/ not serious

But I guess there's still much to be done on the design aspect, so ok =)

Couple of other suggestions: tutorials - a collection of web articles, eg. from knockmeout, tutsplus, etc. mentioning the pubdate (relevancy of the article), and maybe also an FAQ with popular questions from SO.

@brianmhunt
Copy link
Member Author

@webketje Great feedback, thanks. Agree on all points. :)

@brianmhunt
Copy link
Member Author

Noted issue w/ Firefox (via TrackJS): request for http://brianmhunt.github.io/knockout/computed-dependency-tracking.md/a/binding-syntax.html (does not exist)

@brianmhunt
Copy link
Member Author

@IanYates
Copy link

@brianmhunt

  1. Thanks for the blog post. Some really useful stuff in there which I plan to read in detail when I get time
  2. (I know you're busy!!) Any luck on the issues present when loading the site in IE? I started to go down the rabbit hole of debugging it a week or so ago but ran out of time.

@webketje
Copy link

From the blog post, this seems like an ambitious project, and hopefully Knockout can regain some traction with its own website as an impressive showcase.

@brianmhunt
Copy link
Member Author

@IanYates Thanks– would love feedback on the blog post, in case I missed something. As for IE I have not yet looked at it– just haven't had a chance. But it's on the TODO. I did see a number of IE 10/11/Edge connections and they did not report errors on TrackJS ... but maybe that's an error too. lol

@webketje Thanks for the feedback– It'll definitely be great to how the site is received and how well people feel expresses what KO is capable of.

@IanYates
Copy link

@brianmhunt - given you've just closed #1836, if you update the new KO website to use a template polyfill (or replace <template> with <script>) I'm happy to try it out for you.
If you do go the polyfill route could you please provide some information on how you made it work? I tried a couple of simple things in a JSFiddle but didn't have a lot of luck.

@brianmhunt
Copy link
Member Author

@IanYates Template tag polyfill is done; for how it works check out src/entry.js in 8cf9f25 (right at the bottom). Would love to know if it actually works in IE 😁

@AdamWillden
Copy link
Contributor

I was just checking to see if there was any mention of <template> not working for IE on the new site following the bug closure and didn't see one +1 to adding a "note/keypoint" in about that.

Not sure if you're already aware. In the process of looking for the above I noticed the tag '#specifying-a-template' didn't anchor me to the section as expected: http://brianmhunt.github.io/knockout/a/component-registration.html#specifying-a-template

@brianmhunt
Copy link
Member Author

Thanks @AdamWillden – yes, the # pinpoints are not yet working across pages when in single-page mode. Appreciate the heads up.

I was thinking we should add something in the docs about needing to polyfill <template> – where should it go? Probably in the template binding makes most sense. Thoughts?

@AdamWillden
Copy link
Contributor

Yeah template section would make most sense. Still may be worth components making reference to it however especially around the following note:

You're not limited to using elements, but these are convenient (on browsers that support them) since they don't get rendered on their own. Any other element type works too.

@AdamWillden
Copy link
Contributor

In fact I'd just link "on browsers that support them" to the new relevant section in the template.

@IanYates
Copy link

@brianmhunt - great success! It now works in IE 11 :)

I still think that the <template> fix up should somehow be a part of KO. If I go get a component from some other GitHub project (maybe someone makes a nice calendar control or something), if it uses <template> tags in its markup somehow then I can't support IE. Of course I could do a PR and shim their <template> code too, like how you've done (thanks for the link!) but it'd make more sense for KO to do this once, properly, than everyone doing it themselves, sometimes incorrectly.

@ghost
Copy link

ghost commented Jul 30, 2015

@brianmhunt I like previous design more... looks better for "technicians" (even being fun) and it was less mannered...

@Eisenspalter
Copy link

@brianmhunt please change the header font. That's "crime against design".

@brianmhunt
Copy link
Member Author

@maxim-boligatov @Eisenspalter Thanks for the feedback. The visual design is really just a placeholder right now, have no fear. 😉

@Eisenspalter
Copy link

@brianmhunt I trust you. I love the design of your own homepage.

In my experience, one of the biggest hurdle to use knockout are still custom bindinghandlers. It would be great to have a hub where you can upload and grade bindinghandlers.

All examples should be in Typescript too.
Since Google has decided for Typescript, everybody loves and wants Typescript.

@mbest
Copy link
Member

mbest commented Aug 4, 2015

@brianmhunt, I noticed that if you click the same link twice (for example, click "Documentation" and then click it again), you'll get two history entries; so going back the first time stays on the same page. This is different from what happens normally: clicking a link that doesn't change the URL doesn't add a history entry.

@brianmhunt
Copy link
Member Author

Thanks @mbest; should be fixed dfbcc68

@AdamWillden
Copy link
Contributor

@brianmhunt Is the code available somewhere for pull requests? I couldn't seem to find it but I'm being blind no doubt. This time I'll just let you know but next time I'd do a pull request

Live example is broken here: http://brianmhunt.github.io/knockout/a/component-overview.html

Just need to remove this the following(?) <script>{{ like_dislike_registration }}</script>

@brianmhunt
Copy link
Member Author

Thanks @AdamWillden – The code is under my repo at github.com/brianmhunt/knockout under branch gh-pages PRs are most welcome 😁

@brianmhunt brianmhunt mentioned this issue Aug 27, 2015
10 tasks
@brianmhunt
Copy link
Member Author

For folks interested in the style, you may enjoy the latest, and in any case feedback is most welcome.

@mbest mbest modified the milestone: Not assigned Dec 2, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests