Bladeren bron

Challenge 3: Website recommender.

- Very primitive recommendation logic and UI.
Frederic G. MARAND 8 jaren geleden
bovenliggende
commit
37738e8f20
6 gewijzigde bestanden met toevoegingen van 90 en 1 verwijderingen
  1. 29 0
      client/client.js
  2. 4 0
      client/navbar.html
  3. 39 0
      client/page_recommend.html
  4. 9 0
      client/page_recommend.js
  5. 8 0
      client/website_item_teaser.html
  6. 1 1
      lib/lib.js

+ 29 - 0
client/client.js

@@ -14,6 +14,35 @@ Router.route("/", function () {
   this.render("page_home", { to: "contents" });
 });
 
+Router.route("/recommend", function () {
+  let likedDocs;
+  let recommended;
+
+  if (isLoggedIn()) {
+    let userId = Meteor.userId();
+    recommended = [];
+    let aWords, similar, wordsRegex;
+    likedDocs = Websites.find({ plus: { $in: [userId] }}).fetch();
+    likedDocs.forEach(function (liked) {
+      aWords = liked.words.split(' ');
+      wordsRegex = new RegExp(aWords.join(' .*'));
+      let criteria = {
+        _id: {$ne: liked._id},
+        words: { $regex: wordsRegex }
+      };
+      similar = Websites.find(criteria).fetch();
+      recommended.push({ liked, similar });
+    });
+  }
+  else {
+    recommended = null;
+  }
+  this.render("page_recommend", {
+    to: "contents",
+    data: { recommended }
+  });
+});
+
 Router.route("/search/:search", function () {
   const search = this.params.search;
   this.render("page_search", {

+ 4 - 0
client/navbar.html

@@ -9,6 +9,10 @@
       </div>
 
       <div id="navbar" class="navbar-collapse collapse">
+        <ul class="nav navbar-nav navbar-left">
+          <li><a href="/recommend">Recommendations</a></li>
+        </ul>
+
         <!-- navbar-rights stacks right to left -->
         <ul class="nav navbar-nav navbar-right">
           <li class="active"><a name="login-buttons">{{> loginButtons align="right" }}</a></li>

+ 39 - 0
client/page_recommend.html

@@ -0,0 +1,39 @@
+<template name="page_recommend">
+  {{#unless isLoggedIn }}
+    <div class="jumbotron">
+      <p>You need to be logged in to get personalized recommendations.</p>
+    </div>
+  {{else}}
+    <table class="table table-striped">
+      <thead>
+        <tr>
+          <th>Because you liked...</th>
+          <th>You might like</th>
+        </tr>
+      </thead>
+      <tbody>
+        {{ log }}
+        {{#each recommended }}
+          <tr>
+            <td>
+              {{> website_item_teaser liked }}
+            </td>
+            <td>
+              {{#if similar}}
+              <ul>
+                {{#each similar}}
+                  <li>
+                    {{> website_item_teaser }}
+                  </li>
+                {{/each}}
+              </ul>
+              {{else}}
+                <p>No similar site found.</p>
+              {{/if}}
+            </td>
+          </tr>
+        {{/each}}
+      </tbody>
+    </table>
+  {{/unless}}
+</template>

+ 9 - 0
client/page_recommend.js

@@ -0,0 +1,9 @@
+/**
+ * Client code for the page_recommend template.
+ *
+ * - helpers
+ */
+
+Template.page_recommend.helpers({
+
+});

+ 8 - 0
client/website_item_teaser.html

@@ -0,0 +1,8 @@
+<template name="website_item_teaser">
+  <ul>
+    <li><a href="/site/{{ _id }}">{{ title }}</a></li>
+    <li>{{ description }}</li>
+    <li>URL: <a href="{{ url }}">{{ url }}</a></li>
+    <li>Words: {{ words }}</li>
+  </ul>
+</template>

+ 1 - 1
lib/lib.js

@@ -24,7 +24,7 @@ toWords = (doc) => {
   const aLCWords = aWords.map(function (s) { return s.toLocaleLowerCase(); });
   const aDWords = _.uniq(aLCWords);
   const aDSWords = aDWords.sort();
-  const result = aDSWords.join(" ");
+  const result = aDSWords.join(" ").trim();
   Meteor._debug(doc, result);
   return result;
 };