I’ve finally made private messaging available to all. Verified registered members can access their message box at http://andriasang.com/msg/.
(“Verified” just means that I’ve determined that you’re not a spammer. If you’re a recently registered member, you will not be verified until you’ve posted a comment that convinces me you’re not trying to sell shoes to people. You can also send a message to the site contact form and I’ll probably bump you up.)
Messages are “conversation” based, meaning once you start a message with someone, you’ll see the back-and-forth conversation in the same view. New messages auto load. I’m not sure if this is fast enough for chatting, but you can try!
To start a new conversation, click on the “New” button:
You can enter recipients in the recipient field. Suggestions will be shown through a slightly buggy auto completer.
There’s no limitation on the number of recipients, but I haven’t fully tested out the effects of having masses of recipients, so you may want to limit your messages to just two or three.
For convenience, I’ve also added “send private message” links to the little user profiles in comments.
You’ll only see these links if you’re capable of sending messages. If you don’t see the link, you’re one of 1) not logged in, 2) an unverified member, or 3) you’ve been blocked from sending messages.
The messenger uses such technology as Node.js, WebSockets and the HTML5 history object. History lets you browse your mail box without the page refreshing. The URL bar still changes as you navigate, so you can easily hot link to messages.
Node and WebSockets are used for the real time elements. This is part of a larger real time layer I’ve been adding to the site. I’ll share details in a separate post.
The message system is early, so it may be buggy. The main list view has some known ordering issues, for instance.
If you see another bug, please report it using… the the very messenger that’s not working for you! (If that’s too much irony for you, you can also use the contact form, which is just a plain old HTML text field without the javascript doo-dats.)
Feel free to send me a message to suggest new features. I already have a bunch of things that I hope to add when I get a chance (maybe post Tokyo Game Show-ish), including:
And so forth…
I’ve added a couple of in-development organizational features to the site.
Content is now organized into “topics.” These are just like tags, but they can be localized to specific events or happenings – topics, in other words.
Here are some examples
Some topics are part of a hierarchy. In the above, Sales & Rankings is a top level topic. containing all sales and ranking related stories that appear on the site It’s what one would normally call a tag. Weekly Ranking (8/13) is a local level topic containing just sales stories for the week of August 13. It currently has just two items, but there will be a few more stories when Dengeki releases its rankings and when Media Create shares shipment percentages later in the week. All stories under a local level topic also appear in the higher level topic.
You can think of a local level topic as like a thread you’d see on a message board. Most message boards will have a single thread for all the ranking stories covering the week of August 13, rather than individual threads for the individual stories or a single mega thread covering all sales and ranking stories ever.
This topic system is part of a central organization system that will hopefully be in place over the coming weeks.
You may have noticed that I also resurrected “Flying Get.” For newer readers, Flying Get is an old column I used to do where I’d assemble all the weekly magazine leaks in one story, updated throughout the day (here’s an example). I’ve since switched to separate stories, which is easier to follow (although, admittedly, not as “fun”). The new Flying Get is a topic that gathers all the flying get stories for the week. This includes stories that I write, and links to Japanese stories. View this week’s Flying Get here.
Links to the topic page can be found at the top of the articles and in the article preview blurbs. There’s currently no index for the topics.
There are a couple of issues which I’m disclosing due this site’s policy of disclosing when there are a couple of issues.
On the front page, there’s now an “options” menu. You can select to toggle Japanese stories on/off, English stories on/off and links on/off.
Links are just links to external content. It’s pretty much the only type of Japanese content on the site. I haven’t been doing links to English content, but I may start doing so now, especially when Tokyo Game Show comes around (since I won’t be able to go to Japan this year – BOO). If you just want good old Andriasang.com content, keep the link button off, which is the default state.
Pro tip: by keeping the Japanese option on, you’ll get links to content that I won’t necessarily write about in English or content that I’ll write about in English later in the day. Check out all this stuff from the Japanese list:
I usually steal all Famitsu.com’s screenshots using my sweet image stealing script, so even if you can’t read the text, you can see the pretty pictures.
I’ve relaunched the site’s main search tool. You can now conduct searches via the search box in the upper right.
This means that there are now five different ways to search for stuff on the site. You can type something into the box at the upper right and you’ll receive results from the articles and database (images and other types will be added soon). In the individual sections for the articles, images and database, you can do more advanced searches – specifying date for the article search, publisher, platform and item type (game, peripheral, person, etc.) for the database search, and size and proportion for the image search. You can also do in-page searches by highlighting a term while reading an article.
Look below for some technical details about my search system.
The reason it took me some extra time to make the full search tool is because of two considerations:
For the first problem, I used a Pinterest-style wall of results. When you scroll to the bottom, more results are loaded automatically.
I personally find this type of presentation unreadable, but I wanted to play around with different presentation styles, so I went with this route. I’m not sure if I will keep it in this form.
Like Pinterest, the individual item blurbs are of fixed width but varying height. This currently causes the bottom of the page to be uneven – sometimes extremely so, if some columns have lots of items without images. I can think of a couple of ways to fix this – adding new results to shorter columns first, for instance. I’ll implement those schemes later. I also currently don’t assign heights to my images, which causes the page to animate downward when new results are loaded in.
For the second problem, the sorting scheme, Solr and Lucene gives you plenty of power in this area. I assign a score to individual documents at index time and give boosts to certain fields during query time. When grabbing the results, I make Solr sort by score.
To determine a document’s score at index time, I use two broad considerations:
I compute the document’s recency score and popularity score, then add them together to get the full document’s score.
The meaning of recency and popularity depends on the type of document.
Recency For content and images, recency means when the content was posted. Newer content has a higher recency score. For database entries, recency means how close to the current date the item’s release date is. Items that were just released or are soon to be released have higher recency scores compared to older items and items that are farther off. Popularity For content, popularity includes page views, number of comments, and social media cues like “likes” and “retweets” and so-forth. For database items, popularity includes social media cues, and the number of recent images and articles. I currently don’t include the pageviews or social media cues, as my database at present can’t store such “computed” fields (this will change super soon)For the actual computations, I’ve totally forgotten all my college maths (I’m the Berkeley math department’s most shameful outcome) but I found a few recommendations at this page.
Recency is computed using a reciprocal function A / ( M * X + B)
M, A and B are constants. For content, X is the difference between the current time stamp and the time stamp of the article. For database items, X is the absolute value of the difference between the current date and the release date (so games released three weeks ago get the same score as games coming out three weeks for now – that may not be a good idea).
Changing the constants changes the shape of the curve. You can make the curve really steep so that articles that you just posted have a super huge boost, making sure they will be at the top of results.
See page 7 of the above link for further details on the function’s use.
Popularity is computed using this:
(0.6 * recent) + (0.4 * lastWeek) + (0.2 * lastMonth) …
The “recent”, “lastWeek,” etc. is a figure that reflects the amount of popularity for that given time period. For content, I just have the number of comments for now, but will include page views soon. For database items, I use the number of images and articles added for the item over the period. The multipliers were obtained by trial and error.
Outside of the document score, I also have a query-time boost system in place when the user is doing a text search. Each document has three main text fields of decreasing importance. These three are boosted differently.
For content, the text of the headline and strapline go in the first text field, which gets the biggest boost. The text of the first couple of hundred words and the names of all related objects go in the second text field. The text of the rest of the document goes in the third text field.
For database items, the various names – english, Japanese, roman, etc. – all go in the first field. The second field has the names of related objects – for a game, this could be PlayStation 3 (the platform), Square Enix (the publisher), and the development staff. Including those related object fields means that entering Square Enix into the search box will return all Square Enix published games. Square Enix the company (and a game with the word “Square Enix” in the title) should come out on top of all those games, though, because “Square Enix” is in the first text field.
The actual numbers for all the boosts, the way you combine the different boosts, and the determination of what items go in what fields is a part of the search engine’s “secret sauce” (to borrow a term used by people who probably need to be punched in the face). I’m sure there’s a lot of science to it, but I just played around with the figures until I was happy with the results.
The MooTools Class construct lets you pass an options array to the constructor. This means you can have variable parameters – a useful feature when you don’t want to commit to a particular interface, or when you have a large number of options that may or may not be present.
The options can be assigned default values by setting an options array in the Class definition. This default options array works with inheritance, so subclasses inherit the parent class options and can also redefine defaults and add new options.
I wanted similar functionality in PHP. Solarium, one of my most heavily used libraries, comes with a “Configurable” class from which it inherits. This lacks the inheritance functionality for the default options, which is an essential feature.
After a bit of playing around with things with fancy names like “late static binding” I managed to modify the Solarium Configurable class to get something that works the right way:
Use it like this:
I’m not sure if using this sort of configuration scheme in PHP is considered good programming practice or not, but if you find that you do need configurable classes, now you have a base class to start you off.
I had a bit of contract programmer work recently (my first contract programming work since Elvis died) which required that I read up on a MooTools class called “Behavior.” Behavior is part of the Clientcide library, which I use heavily on my site. My autocompleter (which won’t be user-facing until I get around to opening up personal message support) is from Clientcide, for instance.
I’d never used Behavior itself, but I’ve started incorporating it more fully into my site because I really like it. Behavior fixes one big issue many have with regular old Javascript, something I think has been officially named “selector hell.”
Normally, during a page’s instantiation, you use selectors to select elements to which you want to add javascript functionality. For instance, let’s say you want to hijack a link and make it output a silly message. Normally, you’d do this:
<a id="sillylink" href="/newpage/">Click me to go to a new page</a>
With Behavior, you’d instead do this:
<a data-behavior="LinkHijack" href="/newpage/">Click me to go to a new page</a>
By assigning a data-behavior property to an element, you tell the Behavior class, which is instantiated via the new Behavior().apply(document.body) call at the end of the domready event handler, to call the “setup” function associated with that particular data-behavior property on the element. In this case, a click handler is added to the link.
That may look like a lot of extra code for nothing, but here’s where behavior really becomes powerful:
<a data-behavior="LinkHijack"
data-LinkHijack-text="Ooga Booga"
data-LinkHijack-useAlert=true
href="/newpage/">Click me to go to a new page</a>
The difference for this longer example is that I’m now passing parameters to the behavior handler. The parameters can be passed directly in the html tag as data-{BehaviorClassName}-{OptionName} or as a json version of a javascript object specifying the parameters, specified with data-{BehaviorClassName}-options. In the behavior handler, you can also specify defaults which the options will automatically take if not specified in the html.
In the above example, I’ve made it so that you can pass a text field containing the message that is output on click, a useAlert field which specifies whether to use alert or console.log() for output, and a preventDefault field which specifies whether to stop the link click event from proceeding.
The point of doing things this way is that you can let designers working with html specify what types of behaviors they want attached to items, and also specify the parameters they want passed to those behaviors. This eliminates the need for a programmer to come in between, allowing for designers to easily change the presentation and functionality of a site without a bit of coding. “Behavior” is like a programming-free interface into your javascript code.
I’m not sure if Behavior is being supported anymore, but it’s something whose basic functionality I think I could make myself should the need arise, so I’ve been switching many aspects of my site to it of late.
Here’s what the Behavior instantiation section of my main javascript file looks like. It’s pretty long, but I’ll explain the various items below:
I have Behavior automatically pick out the following elements:
Tooltips
This uses the Mootools tips class, but I added a couple of properties for specifying the text without using the title or ref fields, as the tips class wasn’t blocking the default ugly html tip thing from appearing.
Date picker
This uses the excellent Mootools DatePicker class to make a date picker appear when the user clicks on an input. I’ve added an option to automatically submit the enclosing form when the date has been selected.
Animated anchor
This makes anchor links – links with the “#” in the url – animate to their destination on the page using the MooTools Fx.Scroll class. You can pass all the FX.Scroll options.
Send message tags
This opens a message composer window, which allows the reader to send a message to the recipient specified in the options. The message composer component is part of my site’s messaging app, which is too specific to the site for me to share at present. When you click on the byline at the top of articles, this bit of behavior is being triggered. The “require” function in there is my own little “module” loader which loads all the images, css files and javascript files required for a module, then calls a callback.
Pin-on-scroll
This uses David Walsh’s ScrollSpy class and the MooTools More Pin module to make elements stick in place when the page has scrolled a certain distance. You can see it in action on the index pages, where the top bar will scroll up then stick in place, and in articles, where the right bar will do the same. A “pinned” class is assigned to the element upon pinning, allowing you to style it. This is how I make the article right bar element fade in/out upon scrolling – there’s no javascript involved in that area.
Dropmenu
This adds clickability to the site’s dropdown menus. My menus are mostly open-on-hover, but I do need clickability for more complex menus.
A couple of other points:
I finally got around to fixing the site’s darn inline search tool, which hasn’t been working since… well, I don’t know when it stopped working, really!
Inline search means that you can highlight some text in an article or comment and a window will pop up with search results from around the site that matches the highlighted text.
Click on any of the links to open the content in a new window.
A couple of technical points:
The search widget has a Twitter/Facebook-style auto loading thing where when you scroll to the bottom more items will load in.
It also uses polling on the text field to determine when you make changes, which is why there’s no search button. This area is a bit unrefined right now.
The results only show articles at present. I’ll be adding database and image support shortly.
If you’ve upgraded to the alpha version of Solr 4 (as far as I can recall, this wasn’t a problem in the development trunk versions from a couple of months back), and you kept your schema.xml file, you may have noticed that deleteByQuery commands no longer work.
Here’s the simple fix (posted as an image because I can’t make damn Tumblr output code nicely).
Make sure that “version” statement is in your schema. I don’t know why it works, but it does.
Incidentally: if you’re using Solr through PHP, I recommend Solarium as an API. It seems to do just about everything, is well documented, and is updated with amazing frequency. It’s had support for Solr 4 features like join for some time now (although I believe I’m doing join manually).
I’ll detail how I’m using join in a later post.
… although their OAUTH instructions are lacking.
(I’m using the Tumblr API to integrate this blog onto my userpage at my site. Other users will be able to do the same if they wish.)
BTW, I’ve been back in America for two and a half years now and I still don’t know if I’ve actually seen a hipster, but I do know that I hate them. Some people say I should go to SF, where they’re apparently plentiful in certain districts.
This is my “personal” blog, but outside of the occasional pics of my adorable nephew Dylan (see attached pic) I’ll mostly be using it as a development blog for Andriasang.com. I’ll be introducing new features here as I implement them, occasionally making fun of how Japanese people speak English, so please confirm it occasionally.