{"action":"created","comment":{"url":"https://api.github.com/repos/nus-cs2103/website/pulls/comments/48675990","id":48675990,"diff_hunk":"@@ -0,0 +1,347 @@\n+# Site-Wide Search Feature\n+### Author: Stefano Chiesa\n+\n+## Overview\n+Without a dedicated search feature, users tend to have problem searching for specific keywords — i.e., users might not know the page which the specific keywords resides, browser built-in search function is not flexible enough for keyword searching. To solve these problems, a dedicated search feature is needed. This dedicated search feature aims to help users searching for specific keywords from the whole CS2103/T website with ease.\n+\n+## Design\n+\n+### Introduction\n+Search page is analogous to the index section of a book in terms of how keywords are linked to relevant page and the table of contents section in terms on how keywords are organized. Search page can also be viewed as a sitemap of CS2103/T website, in such way that relevant keywords from the whole CS2103/T website are listed on this page.\n+\n+There are other approaches to implement a search feature. Below are some approaches that are considered:\n+\n+<table>\n+    <tr>\n+        <th>Approach</th>\n+        <th>Pros</th>\n+        <th>Cons</th>\n+    </tr>\n+    <tr>\n+        <td>\n+            Use Google Custom Search Engine\n+        </td>\n+        <td>\n+            <ul>\n+            <li>Powerful search algorithm, more relevant result</li>\n+            </ul>\n+        </td>\n+        <td>\n+            <ul>\n+            <li>More suitable on website with many pages</li>\n+            <li>Less control over search page (Advertising, Uncustomizable search page, etc..)</li>\n+            </ul>\n+        </td>\n+    </tr>\n+    <tr>\n+        <td>\n+            Crawl website to build index automatically\n+        </td>\n+        <td>\n+            <ul>\n+            <li>Everything can be done programmatically</li>\n+            </ul>\n+        </td>\n+        <td>\n+            <ul>\n+            <li>Less relevant results</li>\n+            <li>Difficult to be organized accurately</li>\n+            </ul>\n+        </td>\n+    </tr>\n+    <tr>\n+        <td>\n+            Add relevant keywords to build index manually\n+        </td>\n+        <td>\n+            <ul>\n+            <li>More relevant results</li>\n+            <li>Full control over search page, keywords displayed, and keywords organization</li>\n+            </ul>\n+        </td>\n+        <td>\n+            <ul>\n+            <li>Requires a lot of manual works</li>\n+            </ul>\n+        </td>\n+    </tr>\n+</table>\n+\n+Although a lot of works have to be done manually, adding keywords manually seems to be the best approach. Relevance of the search results and full control over the search page is a really important point to have. Also, considering the website being an open source project, adding keywords can be done by crowdsourcing. \n+\n+### User Interface\n+Although search page is analogous to the index section of a book, keywords are not listed in alphabetical order. Instead, keywords are organized in a tree-like structure like the table of contents section of a book. This way, context of a keyword are clearly displayed and linked with a page or section related to this keyword.\n+\n+As the number of keywords on the page might go up to hundreds, it becomes necessary to let users have a better control of number of keywords displayed. Therefore, expanding and collapsing is implemented to show/hide children keywords of a keyword.\n+\n+### Data Storage\n+Just like the index section of a book, keywords are selected manually not automatically. Information and structure of these keywords are added manually and stored inside HTML file of the page itself.\n+\n+The main purpose of storing these keywords inside a HTML file is to make it easy and simple to add new keywords to search page. Three custom HTML elements (`main-category`, `category`, `keyword`) are introduced to make the keywords page easier to understand and modify.\n+\n+### Search Function\n+Search function is implemented on the page and it is designed to be flexible. For instance, searching for `activity` will also returns `Activities` as a result.\n+\n+The implemented nature of searching done by the search function is an OR search, that is results that are displayed must contain only at least of a word from users' query. This implemented nature is considered more flexible than an AND search nature that is more strict such that a result must contains all words from users' query.\n+\n+## Implementation\n+\n+### User Interface\n+\n+Although user interface is mainly implemented in HTML, Javascript is used many times to modify Document Object Model(DOM) of the search page. The three custom elements are compiled into template HTML fragments by [AngularJS templating engine](https://docs.angularjs.org/guide/templates), this prevents many repetition of code fragments inside the HTML file since the HTML file also used as data storage. \n+\n+To have a better user experience, Javascript with help of jQuery also is used to listen for events such as expanding and collapsing subcategory.\n+\n+### Data Storage\n+Keywords data are stored inside HTML file of the search page. But we decided not to use plain HTML to store the keywords. Three custom HTML elements are introduced using [AngularJS directives](https://docs.angularjs.org/guide/directive) to have more human readable data. When search page is loaded, [AngularJS](https://angularjs.org/) will try to collect the keywords from custom HTML elements and convert it into a Javascript array to be processed further by the search function.\n+","path":"doc/searchFeature.md","position":97,"original_position":97,"commit_id":"e945c6b0cffce0018489993e2ff9a581d88b2f04","original_commit_id":"e945c6b0cffce0018489993e2ff9a581d88b2f04","user":{"login":"damithc","id":1673303,"avatar_url":"https://avatars.githubusercontent.com/u/1673303?v=3","gravatar_id":"","url":"https://api.github.com/users/damithc","html_url":"https://github.com/damithc","followers_url":"https://api.github.com/users/damithc/followers","following_url":"https://api.github.com/users/damithc/following{/other_user}","gists_url":"https://api.github.com/users/damithc/gists{/gist_id}","starred_url":"https://api.github.com/users/damithc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/damithc/subscriptions","organizations_url":"https://api.github.com/users/damithc/orgs","repos_url":"https://api.github.com/users/damithc/repos","events_url":"https://api.github.com/users/damithc/events{/privacy}","received_events_url":"https://api.github.com/users/damithc/received_events","type":"User","site_admin":false},"body":"May be you can give sample code for the two approaches so that readers can compare the two visually?","created_at":"2016-01-01T04:17:18Z","updated_at":"2016-01-01T04:17:18Z","html_url":"https://github.com/nus-cs2103/website/pull/120#discussion_r48675990","pull_request_url":"https://api.github.com/repos/nus-cs2103/website/pulls/120","_links":{"self":{"href":"https://api.github.com/repos/nus-cs2103/website/pulls/comments/48675990"},"html":{"href":"https://github.com/nus-cs2103/website/pull/120#discussion_r48675990"},"pull_request":{"href":"https://api.github.com/repos/nus-cs2103/website/pulls/120"}}},"pull_request":{"url":"https://api.github.com/repos/nus-cs2103/website/pulls/120","id":54614178,"html_url":"https://github.com/nus-cs2103/website/pull/120","diff_url":"https://github.com/nus-cs2103/website/pull/120.diff","patch_url":"https://github.com/nus-cs2103/website/pull/120.patch","issue_url":"https://api.github.com/repos/nus-cs2103/website/issues/120","number":120,"state":"open","locked":false,"title":"Implement site wide search #38","user":{"login":"zeulb","id":9133338,"avatar_url":"https://avatars.githubusercontent.com/u/9133338?v=3","gravatar_id":"","url":"https://api.github.com/users/zeulb","html_url":"https://github.com/zeulb","followers_url":"https://api.github.com/users/zeulb/followers","following_url":"https://api.github.com/users/zeulb/following{/other_user}","gists_url":"https://api.github.com/users/zeulb/gists{/gist_id}","starred_url":"https://api.github.com/users/zeulb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zeulb/subscriptions","organizations_url":"https://api.github.com/users/zeulb/orgs","repos_url":"https://api.github.com/users/zeulb/repos","events_url":"https://api.github.com/users/zeulb/events{/privacy}","received_events_url":"https://api.github.com/users/zeulb/received_events","type":"User","site_admin":false},"body":"Fixes #38 \r\n\r\nPreview: http://zeulb.github.io/website/","created_at":"2015-12-27T08:57:23Z","updated_at":"2016-01-01T04:17:18Z","closed_at":null,"merged_at":null,"merge_commit_sha":"81f18fd5f1fbdd5f8948ae6ff4e7f520e0a02f16","assignee":{"login":"wkurniawan07","id":7261051,"avatar_url":"https://avatars.githubusercontent.com/u/7261051?v=3","gravatar_id":"","url":"https://api.github.com/users/wkurniawan07","html_url":"https://github.com/wkurniawan07","followers_url":"https://api.github.com/users/wkurniawan07/followers","following_url":"https://api.github.com/users/wkurniawan07/following{/other_user}","gists_url":"https://api.github.com/users/wkurniawan07/gists{/gist_id}","starred_url":"https://api.github.com/users/wkurniawan07/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wkurniawan07/subscriptions","organizations_url":"https://api.github.com/users/wkurniawan07/orgs","repos_url":"https://api.github.com/users/wkurniawan07/repos","events_url":"https://api.github.com/users/wkurniawan07/events{/privacy}","received_events_url":"https://api.github.com/users/wkurniawan07/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/nus-cs2103/website/pulls/120/commits","review_comments_url":"https://api.github.com/repos/nus-cs2103/website/pulls/120/comments","review_comment_url":"https://api.github.com/repos/nus-cs2103/website/pulls/comments{/number}","comments_url":"https://api.github.com/repos/nus-cs2103/website/issues/120/comments","statuses_url":"https://api.github.com/repos/nus-cs2103/website/statuses/e945c6b0cffce0018489993e2ff9a581d88b2f04","head":{"label":"zeulb:site-wide-search","ref":"site-wide-search","sha":"e945c6b0cffce0018489993e2ff9a581d88b2f04","user":{"login":"zeulb","id":9133338,"avatar_url":"https://avatars.githubusercontent.com/u/9133338?v=3","gravatar_id":"","url":"https://api.github.com/users/zeulb","html_url":"https://github.com/zeulb","followers_url":"https://api.github.com/users/zeulb/followers","following_url":"https://api.github.com/users/zeulb/following{/other_user}","gists_url":"https://api.github.com/users/zeulb/gists{/gist_id}","starred_url":"https://api.github.com/users/zeulb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zeulb/subscriptions","organizations_url":"https://api.github.com/users/zeulb/orgs","repos_url":"https://api.github.com/users/zeulb/repos","events_url":"https://api.github.com/users/zeulb/events{/privacy}","received_events_url":"https://api.github.com/users/zeulb/received_events","type":"User","site_admin":false},"repo":{"id":47562808,"name":"website","full_name":"zeulb/website","owner":{"login":"zeulb","id":9133338,"avatar_url":"https://avatars.githubusercontent.com/u/9133338?v=3","gravatar_id":"","url":"https://api.github.com/users/zeulb","html_url":"https://github.com/zeulb","followers_url":"https://api.github.com/users/zeulb/followers","following_url":"https://api.github.com/users/zeulb/following{/other_user}","gists_url":"https://api.github.com/users/zeulb/gists{/gist_id}","starred_url":"https://api.github.com/users/zeulb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zeulb/subscriptions","organizations_url":"https://api.github.com/users/zeulb/orgs","repos_url":"https://api.github.com/users/zeulb/repos","events_url":"https://api.github.com/users/zeulb/events{/privacy}","received_events_url":"https://api.github.com/users/zeulb/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/zeulb/website","description":"CS2103 website","fork":true,"url":"https://api.github.com/repos/zeulb/website","forks_url":"https://api.github.com/repos/zeulb/website/forks","keys_url":"https://api.github.com/repos/zeulb/website/keys{/key_id}","collaborators_url":"https://api.github.com/repos/zeulb/website/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/zeulb/website/teams","hooks_url":"https://api.github.com/repos/zeulb/website/hooks","issue_events_url":"https://api.github.com/repos/zeulb/website/issues/events{/number}","events_url":"https://api.github.com/repos/zeulb/website/events","assignees_url":"https://api.github.com/repos/zeulb/website/assignees{/user}","branches_url":"https://api.github.com/repos/zeulb/website/branches{/branch}","tags_url":"https://api.github.com/repos/zeulb/website/tags","blobs_url":"https://api.github.com/repos/zeulb/website/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/zeulb/website/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/zeulb/website/git/refs{/sha}","trees_url":"https://api.github.com/repos/zeulb/website/git/trees{/sha}","statuses_url":"https://api.github.com/repos/zeulb/website/statuses/{sha}","languages_url":"https://api.github.com/repos/zeulb/website/languages","stargazers_url":"https://api.github.com/repos/zeulb/website/stargazers","contributors_url":"https://api.github.com/repos/zeulb/website/contributors","subscribers_url":"https://api.github.com/repos/zeulb/website/subscribers","subscription_url":"https://api.github.com/repos/zeulb/website/subscription","commits_url":"https://api.github.com/repos/zeulb/website/commits{/sha}","git_commits_url":"https://api.github.com/repos/zeulb/website/git/commits{/sha}","comments_url":"https://api.github.com/repos/zeulb/website/comments{/number}","issue_comment_url":"https://api.github.com/repos/zeulb/website/issues/comments{/number}","contents_url":"https://api.github.com/repos/zeulb/website/contents/{+path}","compare_url":"https://api.github.com/repos/zeulb/website/compare/{base}...{head}","merges_url":"https://api.github.com/repos/zeulb/website/merges","archive_url":"https://api.github.com/repos/zeulb/website/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/zeulb/website/downloads","issues_url":"https://api.github.com/repos/zeulb/website/issues{/number}","pulls_url":"https://api.github.com/repos/zeulb/website/pulls{/number}","milestones_url":"https://api.github.com/repos/zeulb/website/milestones{/number}","notifications_url":"https://api.github.com/repos/zeulb/website/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/zeulb/website/labels{/name}","releases_url":"https://api.github.com/repos/zeulb/website/releases{/id}","created_at":"2015-12-07T16:01:37Z","updated_at":"2015-12-07T16:01:38Z","pushed_at":"2015-12-31T14:55:20Z","git_url":"git://github.com/zeulb/website.git","ssh_url":"git@github.com:zeulb/website.git","clone_url":"https://github.com/zeulb/website.git","svn_url":"https://github.com/zeulb/website","homepage":null,"size":17595,"stargazers_count":0,"watchers_count":0,"language":"HTML","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"nus-cs2103:master","ref":"master","sha":"961fe912c23c546d0d51f5e52851f8a4deb35b97","user":{"login":"nus-cs2103","id":13566008,"avatar_url":"https://avatars.githubusercontent.com/u/13566008?v=3","gravatar_id":"","url":"https://api.github.com/users/nus-cs2103","html_url":"https://github.com/nus-cs2103","followers_url":"https://api.github.com/users/nus-cs2103/followers","following_url":"https://api.github.com/users/nus-cs2103/following{/other_user}","gists_url":"https://api.github.com/users/nus-cs2103/gists{/gist_id}","starred_url":"https://api.github.com/users/nus-cs2103/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nus-cs2103/subscriptions","organizations_url":"https://api.github.com/users/nus-cs2103/orgs","repos_url":"https://api.github.com/users/nus-cs2103/repos","events_url":"https://api.github.com/users/nus-cs2103/events{/privacy}","received_events_url":"https://api.github.com/users/nus-cs2103/received_events","type":"Organization","site_admin":false},"repo":{"id":41247270,"name":"website","full_name":"nus-cs2103/website","owner":{"login":"nus-cs2103","id":13566008,"avatar_url":"https://avatars.githubusercontent.com/u/13566008?v=3","gravatar_id":"","url":"https://api.github.com/users/nus-cs2103","html_url":"https://github.com/nus-cs2103","followers_url":"https://api.github.com/users/nus-cs2103/followers","following_url":"https://api.github.com/users/nus-cs2103/following{/other_user}","gists_url":"https://api.github.com/users/nus-cs2103/gists{/gist_id}","starred_url":"https://api.github.com/users/nus-cs2103/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nus-cs2103/subscriptions","organizations_url":"https://api.github.com/users/nus-cs2103/orgs","repos_url":"https://api.github.com/users/nus-cs2103/repos","events_url":"https://api.github.com/users/nus-cs2103/events{/privacy}","received_events_url":"https://api.github.com/users/nus-cs2103/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/nus-cs2103/website","description":"CS2103 website","fork":false,"url":"https://api.github.com/repos/nus-cs2103/website","forks_url":"https://api.github.com/repos/nus-cs2103/website/forks","keys_url":"https://api.github.com/repos/nus-cs2103/website/keys{/key_id}","collaborators_url":"https://api.github.com/repos/nus-cs2103/website/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/nus-cs2103/website/teams","hooks_url":"https://api.github.com/repos/nus-cs2103/website/hooks","issue_events_url":"https://api.github.com/repos/nus-cs2103/website/issues/events{/number}","events_url":"https://api.github.com/repos/nus-cs2103/website/events","assignees_url":"https://api.github.com/repos/nus-cs2103/website/assignees{/user}","branches_url":"https://api.github.com/repos/nus-cs2103/website/branches{/branch}","tags_url":"https://api.github.com/repos/nus-cs2103/website/tags","blobs_url":"https://api.github.com/repos/nus-cs2103/website/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/nus-cs2103/website/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/nus-cs2103/website/git/refs{/sha}","trees_url":"https://api.github.com/repos/nus-cs2103/website/git/trees{/sha}","statuses_url":"https://api.github.com/repos/nus-cs2103/website/statuses/{sha}","languages_url":"https://api.github.com/repos/nus-cs2103/website/languages","stargazers_url":"https://api.github.com/repos/nus-cs2103/website/stargazers","contributors_url":"https://api.github.com/repos/nus-cs2103/website/contributors","subscribers_url":"https://api.github.com/repos/nus-cs2103/website/subscribers","subscription_url":"https://api.github.com/repos/nus-cs2103/website/subscription","commits_url":"https://api.github.com/repos/nus-cs2103/website/commits{/sha}","git_commits_url":"https://api.github.com/repos/nus-cs2103/website/git/commits{/sha}","comments_url":"https://api.github.com/repos/nus-cs2103/website/comments{/number}","issue_comment_url":"https://api.github.com/repos/nus-cs2103/website/issues/comments{/number}","contents_url":"https://api.github.com/repos/nus-cs2103/website/contents/{+path}","compare_url":"https://api.github.com/repos/nus-cs2103/website/compare/{base}...{head}","merges_url":"https://api.github.com/repos/nus-cs2103/website/merges","archive_url":"https://api.github.com/repos/nus-cs2103/website/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/nus-cs2103/website/downloads","issues_url":"https://api.github.com/repos/nus-cs2103/website/issues{/number}","pulls_url":"https://api.github.com/repos/nus-cs2103/website/pulls{/number}","milestones_url":"https://api.github.com/repos/nus-cs2103/website/milestones{/number}","notifications_url":"https://api.github.com/repos/nus-cs2103/website/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/nus-cs2103/website/labels{/name}","releases_url":"https://api.github.com/repos/nus-cs2103/website/releases{/id}","created_at":"2015-08-23T11:37:17Z","updated_at":"2015-12-17T01:23:27Z","pushed_at":"2016-01-01T01:00:40Z","git_url":"git://github.com/nus-cs2103/website.git","ssh_url":"git@github.com:nus-cs2103/website.git","clone_url":"https://github.com/nus-cs2103/website.git","svn_url":"https://github.com/nus-cs2103/website","homepage":null,"size":17760,"stargazers_count":12,"watchers_count":12,"language":"HTML","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":32,"mirror_url":null,"open_issues_count":43,"forks":32,"open_issues":43,"watchers":12,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/nus-cs2103/website/pulls/120"},"html":{"href":"https://github.com/nus-cs2103/website/pull/120"},"issue":{"href":"https://api.github.com/repos/nus-cs2103/website/issues/120"},"comments":{"href":"https://api.github.com/repos/nus-cs2103/website/issues/120/comments"},"review_comments":{"href":"https://api.github.com/repos/nus-cs2103/website/pulls/120/comments"},"review_comment":{"href":"https://api.github.com/repos/nus-cs2103/website/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/nus-cs2103/website/pulls/120/commits"},"statuses":{"href":"https://api.github.com/repos/nus-cs2103/website/statuses/e945c6b0cffce0018489993e2ff9a581d88b2f04"}}}}