We got nominated! Help us out and vote for GitHub as Best Bootstrapped Startup of 2008. (You can vote once a day.) [ hide ]

public
Description: 10gen forum module
Homepage: http://www.10gen.com/
Clone URL: git://github.com/10gen/core-modules-forum.git
core-modules-forum / search.jxp
100644 194 lines (163 sloc) 6.58 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
<% /**
* Copyright (C) 2008 10gen Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ %>
 
<%
 
/*
 * "highlight" takes an array of search results and an array of search terms.
 * For each search term, it strips the term to its stem and then it uses a regular expression to search
 * for all matching similar words in each result and put them in a highlighted <span> element.
 *
 * An alternative way of doing this would be to take each word of the result and "stem" it, then compare it
 * to each search term, but this was rejected because it is a) uglier than this (if that's even possible) and
 * b) would take forever.
 *
 */
 
var suffix = "able|ible|al|ial|ed|en|er|est|ful|ic|ing|ion|tion|ation|ition|ity|ty|ive|ative|itive|less|ly|ment|ness|ous|eous|ious|s|es|y";
var prefix = "anti|de|dis|en|em|fore|in|im|il|ir|inter|mid|mis|non|over|pre|re|semi|sub|super|trans|un|under";
 
core.text.stem();
// extract up to m words before the search term and n words after for context
function summarize(result, searchterm) {
        var m = 15, n = 20;
        retAr = [];
 
        if(result == null)
            return;
 
        searchterm = Search.queryToArray(searchterm);
        var stem = Stem.stem(searchterm[0]);
        var summary = new RegExp("(\\w+\\W+){"+m+"}("+prefix+")?"+stem+"("+suffix+")?(\\W+\\w+){"+n+"}", "gi");
        match = result.match(summary);
 
        // if there is trailing header and footer
        if(match)
             for(var i=0; i<match.length; i++)
                  retAr.push( "..."+match[i]+"...");
 
        summary = new RegExp("(\\w+\\W+){"+m+"}("+prefix+")?"+stem+"("+suffix+")?(\\W+\\w+){0,"+n+"}\$", "i");
        match = result.match(summary);
        // if there is trailing header
        if(match)
             retAr.push("..."+match[0]);
 
        summary = new RegExp("^(\\w+\\W+){0,"+m+"}("+prefix+")?"+stem+"("+suffix+")?(\\W+\\w+){"+n+"}", "i");
        match = result.match(summary);
        // if there is trailing footer
             if(match)
                  retAr.push(match[0]+"...");
 
        // no trailing header or footer
        summary = new RegExp("^(\\w+\\W+){0,"+m+"}("+prefix+")?"+stem+"("+suffix+")?(\\W+\\w+){0,"+n+"}\$", "i");
        match = result.match(summary);
        if(match)
              retAr.push(match[0]);
 
        return retAr;
}
 
Forum.root.controller();
Forum.root.html.forumheader("Forum | Search Results for \""+request.query+"\"");
Forum.root.data.thread();
Forum.root.html.form();
Forum.root.data.paging();
 
var query = request.query;
 
var threads = Search.search(db.forum.threads, query);
var paging = new Forum.data.Paging(threads, {pageSize: 20, minWindow: 5},
                                   request);
var threads = paging.slice();
Forum.root.html.paging(paging);
 
var cursor = Search.search(db.forum.topics, query );
 
// Search bar
Forum.html.search();
 
 
%>
 
 
<h1>Forum</h1>
 
<script type="text/javascript">
var color = "none";
function toggleHighlight() {
       var all = document.all ? document.all :
           document.getElementsByTagName('span');
       for (var e = 0; e < all.length; e++)
           all[e].style.background = color;
 
       color = color == "none" ? "#FBFAAB" : "none";
}
</script>
 
<div class="match_div">
<%
 
    var query_enc = content.HTML.escape(query);
 
if(threads.length == 0 && cursor.length == 0){
%>
    <div>No search results for "<%= query_enc %>".</div>
<%
}
else{
    print("<div>Search results for \""+query_enc+"\" <input type=\"checkbox\" value=\"highlight\" onclick=\"toggleHighlight()\" checked>Highlight</div>");
if(cursor.length > 0) { %>
    <div class="match_div">
    <%
    Forum.root.html.topictable("Matching topics:", null, cursor, null, [], {createThread: false, editUser: false, createTopic: false, thisid: null, highlight: query}); %>
    </div>
    <%
}
%>
 
<div class="match_div">
 
<%
if(threads.length > 0){ %>
        <h1>Matching <%= allowModule.forum.threadName.toLowerCase() %>s:</h1>
        <%
    for(var i = 0; i < threads.length; i++){
       var starti = i;
       %>
       <div class="threadbox">
       <div class="title">
            <%
            var tops = Forum.html.topicStack(threads[i].topic);
            for(var j=0; j<tops.length; j++) {
                 print('<a href="viewtopic?name='+URL.escape_queryargs(tops[j])+'">'+tops[j]+'</a> &gt; ');
            }
            %>
            <a href="viewtopic?name=<%= URL.escape_queryargs(threads[i].topic.name) %>"><%= threads[i].topic.name %></a> &gt;
            <a href="viewthread?id=<%= threads[i]._id+"&highlight="+query %>"><%= Forum.html.highlight(content.HTML.escape(threads[i].getTitle()), query) %></a>
       </div>
       <%
            var snippets = Search.snippet(threads[i], query, threads[i].SEARCH_WEIGHTS);
            for(var j=0; snippets != null && j < 4 && j < snippets.length; j++) {
                if(snippets[j].text == snippets[j].object.title)
                     continue;
 
                var prettyDate = snippets[j].object.ts.format("MMM d, yyyy '<span class=''time''>' h:mm")+snippets[j].object.ts.format("a").toLowerCase() +"</span>";
                %>
                <div class="content">
                  <div class="meta"><%= snippets[j].object.author_name %> on <%= prettyDate %></div></div>
                <div class="snips">
                <%
                summary = summarize(snippets[j].text, query);
                for(var k=0; k<summary.length; k++)
                     print(Forum.html.highlight(summary[k], query)+"<br />");
                %>
                </div>
                </div>
                <%
            }
            if(snippets && snippets.length > 4)
                print("(First four shown, "+snippets.length+" matching posts in thread)");
            %>
       </div>
       <%
    }
}
else {
     %>
     No matches in <%= allowModule.forum.threadName.toLowerCase() %>s.
     <%
}
}
 
%>
</div>
<input type="button" class="button" onclick="history.back()" value="Back">
</div>
<%
 
Forum.root.html.paging(paging);
htmlfooter();
%>