Bootstrap for Facebook apps - <AUTHOR> http://ckrack.github.com/fbootstrapp? <comment><USER2> I really hate to rant. I love the idea of this and worked on a thing like a "fb bootstrap" By myself for quite a while now.

Having done many fb apps and making heavy use of twitter bootstrap by myself for other projects recently (oh god, app development on lightspeed!) i first looked at it thrilled: hey cool- this will come in handy! But after about 5 seconds: wtf?

This is just twitterbootstrap painted blue. Using this for your facebook apps would NOT give them a genuine facebook look but make them only look cheap.

The typo is not right. Font sizes, line spacing - everything. Forget about the columns. They are twitterstyle, not facebook. Buttons? They are grey and blue, yes - but not facebook style. Tables? Not at all. I could continue this list for every single element! Facebook has unique tabs, unique breadcumbs. Completely missing!

My quick advice for getting a nearly facebook-like style in your appe in seconds: embed their CSS in your header. When you investigate a bit how they build their page elements, you can mimic their style really quick.

And for the "fb bootstrap": nice idea. Awful implementation. Stay away from it. But everyone has to decide for himself - seems like most people like it, tough.

<comment><USER3> Hi Chris, do you think you could extract and share your knowledge and stylesheets the way that FB Bootstrap does?

<comment><USER2> If I manage to spend 1-2 days on cleaning up and documenting my framework (be warned, it's PHP based) I will open a github project and post it here on HN.

<comment><USER4> Php newbie factoid: every single php programmer I know ends up developing a framework of their own.

Why does this happen (appearently) more on PHP than other languages? (please correct me if I'm statistically wrong)

<comment><USER2> Maybe because it's easier than learning an existing one? I don't know.

The reason why I created my facebook framework: there simply is no other.

</comment></comment></comment></comment></comment><comment><USER5> Why did you almost-but-not-exactly replicate Facebook's style conventions?

The small-but-significant differences between this framework and Facebook (e.g. button styling!) will make any app built using this look decidedly sketchy.

<comment><USER6> To me it seems that he wanted to go the CSS3 way rather than the Facebook way of doing things (multiple dom elements for single UI parts).

<comment><USER5> CSS3 won't affect the color of a border or gradient (most of which are wrong).

</comment></comment></comment><comment><USER7> Wonderful. I recently built a Facebook iFrame app and burned so many hours trying to make my app look vaguely inline with what a user expects a facebook. This is absolutely the perfect kit for that. It's a really terrible reflection on Facebook that they didn't provide exactly this themselves.

Every other "platform" provides UI guidelines with libraries/frameworks to allow others build products native to their platform. Facebook have made no good attempt at this, which is why this is a great project!

<comment><USER8> I'm going through this now so I'm equally excited. A little bit off-topic, but how did you deal with the back button problem?

Currently, if my user navigates a few pages deep in my app and clicks the back button, it exits the app and goes back to Facebook. Quite annoying... Thanks!

<comment><USER9> Because the app is in an iFrame, you can just use regular linked files and then the back button works as expected.

If you do that though, there are a few other issues - you may have to account for pages that do/don't have the Facebook signed_request post data - i.e. you probably need to store it in a session or cookie (and deal with the relevant IE7 cookie + iFrame issues by settings P3P header if you support IE7. Can't remember offhand if it is a problem in IE8.)

Obviously more complex apps where navigation is handled through AJAX get tricky when you can't access the container frame. Maybe look into history.js (<https://github.com/balupton/History.js/>) and see if it works in a Facebook app?

<comment><USER8> History.js looks promising. I'll definitely dig deeper. Using regular A tags does not work, however, hence my question.

I decided not to support IE7 since this is a brand new app. It will be IE8+. I had to deal with the P3P issue in the past and it was a pain. Hopefully IE8 isn't as picky.

Thanks for the help! I now have something to investigate.

<comment><USER2> If some other people have also problems with IE, facebook and session cookies, have a look at this reciep, i wrote. The solution is pretty easy. [http://recipes.wearekiss.com/view/platform/problem- solutions...](http://recipes.wearekiss.com/view/platform/problem- solutions/make-ie-keep-session-cookies)

<comment><USER8> I had trouble doing just this, mainly because of how IE handles cookies on 304. I used this Gem for a Rails app (~1 year ago): <https://rubygems.org/gems/rack-p3p>.

</comment></comment></comment></comment></comment></comment><comment><USER10> Brilliant. That said, as someone working heavily with Bootstrap these days, I suggest that you rebase this off of the 2.0-wip branch as a lot has changed (for the better) there.

</comment><comment><USER11> Good opportunity: sell themes for twitter bootstrap. Make it a marketplace.

</comment><comment><USER12> This is great! Here's an idea: bootstrap with "pluggable" skin (Twitter, Facebook, Google+) so you can make your app standalone (use Twitter style) or inside Facebook (use Facebook style), etc.

I'm not sure if this bootstrap is already compatible with Twitter's (i.e. as simple as changing CSS file), haven't tried this bootstrap thing, but it would be great if it is!

<comment><USER13> Great idea, however I imagine most applications wouldn't need to be cross- platform.

</comment></comment><comment><USER14> Excellent. I was just working on a project that used Bootstrap, which worked great until I had to implement Facebook notifications (which must be viewed in a canvas app). Bootstrap is too wide for that.

</comment><comment><USER15> Careful when branding your apps to look like Facebook.

[https://developers.facebook.com/docs/guides/policy/policy_ch...](https://developers.facebook.com/docs/guides/policy/policy_checklist/english/)

"App does not use Facebook trademarks or express or imply any affiliation with or endorsement by Facebook"

This is a rather vague statement that I could easily see being used as the justification for squashing someone's app. This is why I've always made sure any FB app I make doesn't completely rip-off Facebook styling but contains enough of my own styling to not appear to be part of Facebook.

</comment><comment><USER16> Great, FB-styled bootstrap. Naturally, the typography is terrible. =[

</comment><comment><USER17> I was recently working on a facebook app and thought of something similar, you have beaten me to it. Great work! Kudos!

<comment><USER18> Here is a similar facebook bootstrap that I started, functional but still a WIP.

<https://github.com/tblobaum/bootstrap/tree/2.0-wip>

</comment></comment><comment><USER19> Great bootstrap, but there seems to be a problem with inline labels in Chrome (Ubuntu 10.10). Twitter's labels work fine though. I played with CSS a bit and the labels don't like Lucida grande, obviously: <http://imgur.com/XJ51Z>

</comment><comment><USER20> Great. I just wish Facebook would provide something like this themselves.

</comment><comment><USER21> Brilliant!!! i foresee less ugly looking apps!

</comment><comment><USER22> Twitter bootstrap turned blue. You could have at least been a bit more creative than creating an almost identical clone.

</comment><comment><USER23> humm.

Given that Facebook apps are completely dominated by large companies these days, I'm puzzled by how useful this would be.

Are people really still building FB applications?

I thought the only real action these days was in the mobile space.

</comment><comment><USER24> I think it looks awesome, it really does! However twitter bootstrap looks really generic therefor can be used any place, Fbootstrapp looks a lot like Facebook and cannot be used for much else beside Facebook apps without looking like a rip off.

<comment><USER25> The info page pretty explicitly says that Fbootstrapp is designed for building Facebook apps; if you're building something that wasn't meant to be viewed within an iframe on FB's page, you're looking at the wrong tool.</comment></comment>


Thank you all, today is my first anniversary at News.YC - <AUTHOR>

Today I read on my profile

  user:	    edu
  created:  365 days ago
 A full year here! Mostly lurking, and seldom commenting and submitting news. One year and it is as good as ever.
I wanted to thank you all guys, and specially PG, for making news.YC possible and for keeping it up fresh, clean and smart.
Thank you very much! <comment><USER2> Congratulations :-)

Especially since it seems that your submissions are interesting and your comments insightful.

Keep up the good work...

</comment><comment><USER3> Thank YOU, edu, for helping to keep it "fresh, clean, and smart". (nice choice of words)</comment>


Creating Your Web App: What Technologies to Use - <AUTHOR> http://tbbuck.com/choosing-technology-for-your-web-app/

<comment><AUTHOR> Post author here once again, any questions or anything that you'd like explained in more detail - please ask away! :)</comment>


The Top 160 Americans Now Control $2 Trillion of Wealth - <AUTHOR> https://peoplespolicyproject.org/2018/01/02/the-top-160-americans-now-control-2-trillion-of-wealth/ <comment><USER2> Walton, Devos, Koch, Mars... seems like I popped out of the wrong vagina.

I get feeling a little bitter, but then I think, well, it would be immoral to tax their wealth at a higher rate than anyone else. Free market and all. Property rights exist, you can't just tax them because you feel like it. Taxation is the highest form of theft, I've heard. Government would just waste that money anyway. I just need to pull my bootstraps harder. I came into an extra $20 yesterday. Trying to decide if I should get my teeth looked at at the local dental hygienist school or treat my wife to a dinner out. I'll try to think like a Walton.</comment>


Reddit is down - <AUTHOR> https://www.reddit.com <comment><USER2> > We are experiencing an issue right now, have identified the problem, and are > implementing a fix.

From [http://www.redditstatus.com](http://www.redditstatus.com)

Pretty impressive to identify and start implementing a fix within 10 minutes.

</comment><comment><USER3> Working fine for me. Partial outage?

</comment><comment><USER4> Reddit is back up again.</comment>


Show HN: JExcel – The JavaScript Spreadsheet (MIT) – Now Trending on GitHub;) - <AUTHOR> https://github.com/paulhodel/jexcel <comment><USER2> Looks fantastic! One question- why is the source code one massive 500-line file? This is why bundlers exist, no?</comment>


Black Mirror: Bandersnatch – Official Trailer [HD] – Netflix - <AUTHOR> https://www.youtube.com/watch?v=XM0xWpBYlNM <comment><USER2> This is off topic for HN. Could you please review the guidelines?

[https://news.ycombinator.com/newsguidelines.html](https://news.ycombinator.com/newsguidelines.html)

<comment><AUTHOR> sorry!</comment></comment>


Is WordPress Founder Matt Mullenweg Threatened by the Jamstack? - <AUTHOR> https://twitter.com/photomatt/status/1302012363655110657 <comment><USER2> Why wouldn't he? tech is evolving and especially when WP can be sometimes behave like a dinosaur

</comment><comment><USER3> The shift away from WP should be a game changer once marketers start working on the Jamstack.</comment>


Anyone from Alameda/Oakland Attending Startup School? - <AUTHOR>

Looking for a car to ride-share to/from Startup school this coming weekend. If you're attending from alameda/SF/Oakland and are open to providing a lift, please contact me.<p>Thanks! <comment><USER2> Hey Sam, how do we get in touch?

<comment><AUTHOR> firstname.lastname@example.com</comment></comment>


Straightening our Backbone: A lesson in event-driven UI development - <AUTHOR> https://code.mixpanel.com/2015/04/08/straightening-our-backbone-a-lesson-in-event-driven-ui-development/

<comment><USER2> This is a great example of "simple is better than easy". It always seems so easy to "just make a callback" in JavaScript/UIs but when things go beyond a very simple UI component things go downhill, FAST. This sort of callback dependency nightmare is so common in workflows adopted by many JavaScript/UI frameworks. It's scary and sad at the same time.

I encourage any JavaScript developer to seriously take a look at ClojureScript + React + core.async for front end development. Not a silver bullet, and there's the learning curve of a new language, but definitely better tools to build the foundation for an asynchronous & inherently complex UI. If the problem/project you're solving/working on is not trivial, the payoffs are there.

<comment><USER3> > It always seems so easy to "just make a callback"

DOM interactions are callback oriented. That's how the DOM is built. That's why people write callbacks at first place. Why would you want people to work differently? the api is what it is. You might think the api is broken, well, it's not the front end developers fault, they didn't write the spec.

> but definitely better tools to build the foundation for an asynchronous & > inherently complex UI.

React and CO are DOM abstractions. Which is fine if you know how the DOM works at first place. The problem is most people don't bother learning how the damn thing really works.

But at the end of the end of day, no front end developer can escape from JavaScript or the DOM. When things break,you still have a big JavaScript stack trace with DOM errors to debug,language A or B,framework X,Y,Z or not.

<comment><USER2> I agree with you that there's no escaping the fundamental way the DOM/JavaScript was setup in the first place - it's too late unfortunately, that ship sailed in the 90s apparently :). I can write at least an article about this stuff, but if you're interested in how core.async specifically helps at least mitigate some of the callback spaghetti hell here's a good starting video [https://www.youtube.com/watch?v=AhxcGGeh5ho](https://www.youtube.com/watch?v=AhxcGGeh5ho)

</comment></comment></comment><comment><USER4> Terrific write up. Recently I've been using the mantra "design transcends (choice of) technology" and nowhere is it more apparent than with front-end frameworks. Using React or whatever is hot will not make much of a difference at scale if the application is not well designed. And conversely, it is possible to design great apps with all sorts of alternatives to the brand du jour. I'm still a big fan of the shiny new stuff, but kudos for applying new and improved design concepts to your existing stack rather than jumping brands under some delusion that it will solve all your problems. The community needs more thinking like this.

<comment><USER5> Definitely. I was surprised at how thoughtful and sane this article is.

</comment></comment><comment><USER6> So, one flaw in the approach they displayed is the mediator is kicking off two asynchronous processes. Yes, naturally race conditions will occur if process A competes with process B. Furthermore, why is a mediator performing business logic? The dispatcher / mediator / router / orchestrator seems to be presented as an active object in of itself. It really shouldn't be.

Rather than manipulating or calling components from your mediator, you could tell a coordinator that coordinates services. Services are then where you're housing your business logic. This allows you to structure these service calls and account for execution order.

>View initialization and render are separate steps

yes

> no events are fired during the app's initial bootstrap/render process

sure

> on a given UI screen, a single top-level mediator takes on all > responsibilities of communication/event-dispatching between subviews

> In practice, the code of the Orchestrator view becomes the centralized > location and source of truth for all inter-widget communication in its > purview

no?

There's a reason why actor systems are a thing. You can't just stuff everything into a central object like it's a flat key/value store. It's better (in my opinion) to form a hierarchy of responsibility. The "Orchestrator" should hire some subordinates and delegate work to them in an effective manner.

You guys must have an insane amount of business logic in your web app for any given UI screen (which as I'm understanding it is different menu options I guess? because otherwise a single UI screen is your entire app). The main takeaway in what I'm saying is a router shouldn't be confused with a component that executes business logic. It's doing too much.

<comment><AUTHOR> > So, one flaw in the approach they displayed is the mediator is kicking off > two asynchronous processes

hmm, seems like the diagram wasn't very clear on that point. there's only one asynchronous action there: making a network request back to the server for fresh data, which by its nature has to be an async op. everything else is synchronous (including Backbone's event handlers).

> The "Orchestrator" should hire some subordinates and delegate work to them > in an effective manner.

this is precisely what's happening: the orchestrator basically does nothing but delegate between subviews and the model layer, ensuring that messages are passed around as appropriate. the text probably didn't make clear enough that this is supposed to happen at any sufficiently complex portion of the UI ("This pattern is repeatable: any sufficiently large or complex area of an app (such as a single route) may hold its own mediator to encapsulate the details of its UI interactions and communicate with the Model layer with a small, well-defined API"). we don't really consider interactions between UI components to be "business logic;" if the 'mediator' started turning into an uber-object with many responsibilities we would probably look at breaking it into services (or putting the right bits back into the model layer), but we try pretty rigorously to avoid premature abstractions...

<comment><USER6> ah, very interesting explanation thank you

</comment></comment></comment><comment><USER7> This is a very good breakdown of a useful pattern. I think they dismiss declarative approaches with too broad of strokes, but there is always room for frank discussion of lighter, straightforward approaches that get the job done. This overlaps with Codecademy's messaging architecture with React presented by Bonnie Eisenman at React Conf [1], except Codecademy took it a step further and dynamically generated the mediator linkage using mixins pertaining to the views in play for a given screen.

We pretty much write desktop apps in this style but run into problems in some complex situations, so I am parsing this for clues to where we may be letting problems sneak in. The rule that programmatic UI updates never raise events may be such a clue, indicating some views are doing too much direct interaction with both local state and subviews.

Question: are there rules to apply to this architecture to help with data modularity up and across the view tree? A lot of the work around React right now has to do with creating techniques to avoid passing state across levels that don't directly depend on it. For example, communicating an event two levels up without involving the intervening parent or communicating across subviews that don't share a common parent. As I read the OP, you have to pass the event all the way up and the state all the way down, coupling the dataflow and triggering rerenders pretty much all along the path.

[1] [https://www.youtube.com/watch?v=ZM6wXoFTY3o&feature=youtu.be](https://www.youtube.com/watch?v=ZM6wXoFTY3o&feature=youtu.be)

</comment><comment><USER8> "Our Unix-inspired development philosophy favors the integration of lightweight, independent apps and components instead of the monolithic mega- app approach still common in web development."

I have essentially ported Unix itself onto the web at [https://www.urdesk.net](https://www.urdesk.net) . You can say that the site itself is a kind of "mega-app", but given that it is an entire OS-in-a-browser that typically "installs" in < 2 seconds, I think it can be forgiven. There is also an app that is a kind of "Hello World" for AI that uses the Speech Recognition and Voice Synth capabilities of the Chrome browser. To hop directly into the AI, you can check out [https://www.urdesk.net/desk?intro=bertie](https://www.urdesk.net/desk?intro=bertie)

The site is now Chrome-only, since I am pretty much going all-in with the whole AI theme, and none of the other vendors include the necessary Javascript API's.

<comment><USER6> I deleted root and it froze. Where can I file a bug report? This is unacceptable.

<comment><USER8> Do you mean: I typed: 'rm /' and the prompt never returned? This didn't actually delete anything, you can always just do a ^C to get the prompt back when it gets stuck like that. I wouldn't consider that a "bug", just an unhandled error condition. More of a "glitch" that will take about 2 seconds to work out. Thanks for the feedback!

EDIT: Already fixed with a nice friendly error message!

<comment><USER6> Hey friend, I was just joking about "This is unacceptable." Sarcasm :) I do `rm -r -- /`. Very cool project.

</comment></comment></comment></comment><comment><USER9> Great write-up.

As far as backbone goes, we've had success using marionette.js to standardize the way we write front-end components and implement common types of view patterns. Curious to see if anyone else has found it to be useful.

<comment><USER10> We've had the same experience. It adds just enough convention on top of Backbone to prevent your application from turning into a ball of mud, while at the same time remaining small enough where you can hold the whole framework (Backbone + Marionette) in your head. I find Backbone + Marionette much simpler, and much easier to reason about than Angular, but keeping it this way still requires developer discipline. Avoid hacks, avoid event soup (which Marionette maybe makes a bit too easy), and follow general object oriented design patterns, and it's not that hard to build a maintainable, scalable Backbone/Marionette app.

</comment></comment><comment><USER11> Good article but one thing to be careful of here is that if you just apply this pattern everywhere then you can end up in a situation where every view is decoupled from every other view and there are way more events in the system than there need to be. This happens more frequently than you would think. In the example given of a date picker this is fine as you can easily see that you might want to re-use the date picker somewhere else. But there are often circumstances where a subview could never be re-used outside of it's parent view. For example suppose I have a main calendar view with subviews showing appointments. The subviews need to inform the main view when the user changes an appointment time so that the main view can re-layout all the subviews. In this case there is no need for the main view to listen for events from subviews. The code will be much simpler and easier to debug if the subview just makes a call to the main view directly (the subview should be constructed with a pointer to the main view). When I look at code in the subview I don't have to guess who may be listening to the event, I can see the call directly. It also means that other views apart from the main view cannot randomly listen sub-view events as a 'quick fix' for some bug.

The point is that javascript tends to lead one down an event driven route. But you should only use events if you want to decouple things. Cohesion is also very important in design because it makes things simpler and more encapsulated. You need to decide what the boundaries of your component are. In this case I want the calendar to be the component, not it's subviews. So within the calendar I will make direct function calls, there are less events in the system and it is easier to think about and debug.

<comment><USER12> But suppose you want to re-use the sub-view in another component, you would then need to clone the functionality and satisfy/remove all the directly coupled invocations.

This is where you have to decide how much coupling to introduce to balance comprehension vs future needs of the project

<comment><AUTHOR> indeed, it's a matter of juggling competing maintainability considerations and there are cases where it can make sense to couple components tightly.

that said, in practice our UIs contain relatively few one-off components, and it often requires less dev friction simply to use the standard event pattern than to weigh borderline cases to shave off a little indirection at the cost of tighter coupling. the problem of "too many events in the system" is avoided by letting complicated components handle events from their own subviews and not just blindly bounce everything down to a global mediator. e.g. if no other views have to know about the 4 dropdowns and slider within MyWidget (and they usually don't), then MyWidget can handle all those subview events itself and simply present a single unified 'i've been updated' event for other consumers. essentially narrow the public apis between different actors in the overall system.

</comment></comment></comment><comment><USER13> Very often articles of this nature end up being either too abstract and too vague or too detailed and I would lose focus midway. This is very finely written.

</comment><comment><USER14> Well written compendium of common design patterns.

I love Backbone for its simplicity but I think most problems come from the use of the views' render function, which encourages the habit to have a _centralized_ way to refresh theirs content.

This is, again, a simple way to think about the process, but often it is not the most performant (and this is what has driven to the clever virtual DOM diff-ing of the recent frameworks).

I normally use what I call 'micro-rendering' functions, a way to change the appearance of a view focusing on the change of single state properties.

</comment><comment><USER15> Great post, thanks.

For some reason the css doesn't get applied to your page when I look at it in firefox.</comment>