I am using a modified jQuery Thesaurus for some project and I want to explain my solution for the case we have a huge terms database.

The original code provides the following functions:

1. checks the content of a HTML node in a webpage for terms against a dictionary

2. marks the found terms and construct links for AJAX calls to the terms definitions

3. on mouseover constructs a tooltip on the fly and populates it with the term definition

My modified version is using a JSON feed instead of the default DB controller, but this is not the subject to discuss in this article.

The js code waits for page to complete then downloads (or loads from DB) the full list of terms as a javascript object. At this moment, if the database has a big number of terms the speed of execution decreases until the tool becomes unusuable. There are reports that over 400-500 terms the solution is already out of question.

Here I want to explain my solution to this problem. I decided that any webpage content should be much more smaller than a list of terms from a database with several thousand of entries (or even 130k entries as mentioned in the above report). In that case it makes sense to pass the text to the DB controller then filter the list of terms only to the terms that actually exists in the target webpage.

Therefore I have modified the project to handle this request: (code was updated to address the issue mentioned in the first commentary)

1. Change this function as follows

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
/**
     * 1) Loads list of terms from server
     * 2) Searches terms in DOM
     * 3) Marks up found terms
     * 4) Binds eventhandlers to them
     */
    bootstrap : function() {
		var words;
		var list;
		$.each(this.options.containers, $.proxy(function(i, node) {
                	words += " " + $(node).text().replace(/[\d!;:<>.=\-_`~@*?,%\"\'\\(\\)\\{\\}]/g, ' ').replace(/\s+/g, ' ');
			list = words.split(" ");
			list = removeDuplicates(list);
			words = list.join(" ");
            }, this));
        $.getJSON(this.options.JSON_TERMS_URI+'&words='+words+'&callback=?', $.proxy(function(data){
            this.terms = this._processResponseTerm(data);
            $.each(this.options.containers, $.proxy(function(i, node) {
                this._searchTermsInDOM(node);
                this._markup(node);
            }, this));
            this.bindUI('body');
        }, this));
    },

You can see I am accessing my JSON feed instead of the DB controller but this is not an issue, the idea remains the same. I am passing the extracted text from the containers declared in the Thesaurus Options.

2. Filter the terms in the DB controller (syntax is for generating a JSON feed)

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
$tgs = $this->get_thesaurus(); //make an array of all terms in the dictionary

$words = $_GET['words']; //load list of unique words from target

$tags = array();

foreach ($tgs as $tag) {
	$list = explode(" ",$tag); //make list of words from each term

	foreach ($list as $word) {
		if (stristr($words, $word)) { //check if any of the words are present at target

			$tags[] = $tag;
			break;
		}
	}
}

return array( //return JSON

  'count' => count($tags),
  'tags' => $tags

);

By using this method the size of the dictionary terms loaded in the javascript object falls back to a small number and the speed of the solution is not anymore compromised. It is true that for webpages with massive content the list of words cannot be sent to the server, but for most of the cases this solution will work well.

Etichete: ,

O traducere în limba română pentru modulul bbPress 2.0.x pentru WordPress.

Se instalează în directorul …/plugins/bbpress/bbp-languages/

bbPress20-ro_RO.zip

733 de șiruri traduse (100%).

(This is bbPress 2.0 plugin translation into Romanian language.)

Etichete:

Discutam mai demult despre înlocuirea HDD cu dispozitive SSD în mediul enterprise. Iată că odată cu lansarea unei noi generații de cipuri Flash numite eMLC (de la enterprise MLC) deja hard-discurile de înaltă performanță pot fi înlocuite cu dispozitive SSD la un preț mai avantajos.

Desigur că deocamdată sunt multe limitări, iar RAMSAN-810, primul sistem de stocare cu eMLC de la TMS este recomandat numai pentru aplicații read-intensive precum cele de data warehousing.

Mai jos este un grafic interesant cu privire la evoluția prețurilor dispozitivelor de stocare.

Etichete: ,

Relevanssi - WordPress Search Done RightRelevanssi este un modul de căutare performant pentru WordPress și WordPress Multisite. El poate fi instalat în două variante, una gratuită și una premium, pentru care se plătește un abonament anual.

Modulul este compatibil cu ultimele versiuni de WordPress și poate indexa orice fel de conținut clasic sau personalizat (custom post types, custom taxonomies, profile utilizatori, comentarii, etc). Rezultatele sunt ordonate după relevanță. conform scorului obținut pe baza mai multor criterii configurabile în zona de administrare.

În versiunea multisite se pot face căutări în mai multe bloguri simultan prin configurarea formularului de căutare și a machetei de afișare a rezultatelor.

Modulul permite evidențierea termenilor căutați atât din căutările proprii cât și din cele externe, de la Google, AOL, Bing, Yahoo.

Oferim aici o traducere profesională a modulului în limba română. Pachetul de traducere conține localizările ambelor versiuni Relevanssi, prin urmare nu contează ce versiune folosiți, pur și simplu plasați fișierele în folderul modulului și traducerea va funcționa automat.

Pentru a accesa modulul urmați linkul din imaginea din dreapta.

Relevanssi free 2.9.9 / Relevanssi Premium1.6 localizare ro_RO

Etichete: ,

Prezentăm în acest scurt articol rezultatele unor teste de viteză pentru dispozitive de stocare de tehnologii diferite, utilizabile în computere personale.

Testul constă în scrierea și citirea unui fișier de 256MB, folosind blocuri de mărime diferită (pe axa Y) și o coadă de 4 comenzi de scriere (una în execuție, trei în așteptare). Despre teoria cozilor în ceea ce privește dispozitivele de stocare am mai scris în studiile de caz corespunzătoare.

Rezultatele au fost exprimate în lățime de bandă disponibilă, anume câți MB se pot transfera într-o singură secundă pe acel dispozitiv de stocare. Măsurătorile IOPS nu sunt foarte interesante pentru calculatoarele personale așa că au fost ignorate în acest test.

Drept concluzie, un disc SSD este foarte util pentru creșterea performaței unui calculator personal. De asemenea sisteme de backup conectate la USB 3 sunt deja o necesitate în cazul configurațiilor de calcul moderne.

În plus vechea idee de a folosi un memory stick pentru accelerarea sistemului de operare Windows se pare că nu mai are deloc aplicabilitate.

Viteze pentru 4 tehnologii de stocare

Etichete: ,

screenshot admin

This plugin creates and maintains one or multiple hierarchies of blogs in the WPMS network.

Download the plugin here: nsh.zip v0.1.0

Newest installation will always be found here: http://wordpress.org/extend/plugins/wpmswpmu-network-sites-hierarchy/

 

Etichete:

Copy the code below into a new php template file inside the Twenty Eleven theme, then create a blank page using this template. Accesing the page will list the latest posts from all WPMS network sites except the main site.

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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
<?php
/**
 * Template Name: WPMS Recent Posts
 * Description: A Page Template that display recent posts from all WPMS network
 * Author: Richard Vencu
 * Template url: http://richardconsulting.ro/blog/WPMS_template_latest_network_posts/
 *
 * @package WordPress
 * @subpackage Twenty_Eleven
 * @since Twenty Eleven 1.0
 */

get_header(); 

/////////////  RETRIEVE SORTED LATEST POSTS FROM WPMS NETWORK (EXCEPT MAIN SITE)  /////////////////////

/*
Parameters
==========

$how_many (integer): how many recent posts are being displayed.
$how_long_days (integer): time frame to choose recent posts from (in days).
$sort_by (string - post_date/post_modified/post_title/comment_count/): You can short the lattest post by positing date (post_date) or posting update (post_modified).
$sort_order (constant - SORT_ASC or SORT_DESC, default is SORT_DESC

Returns
======

Array of blog ID and post ID in ordered form

*/

function wpms_latest_post($how_many = 10, $how_long_days = 30, $sort_by = 'post_date', $sort_order = SORT_DESC ) {
	global $wpdb;

	//first, gat all PUBLIC blog id

	$query = "SELECT blog_id FROM $wpdb->blogs WHERE blog_id != '1' AND public = '1' AND archived = '0' AND mature = '0' AND spam = '0' AND deleted = '0'";
	$blogs = $wpdb->get_col($wpdb->prepare($query) );

	$recentPosts = array();

	/* Build query args, we retrieve the $how_many number from each site since maybe there are sites with zero recent posts */
	$args = array(
		'post_type' 		=> 'post',
		'post_status' 		=> 'publish',
		'numberposts' 		=> $how_many


	);

	if ( is_array($blogs) ) {
		/* filter_where - filtering function that will add our where clause to the query */
		$filter_where = create_function ('$where','return $where .= " AND post_date > \'' . date('Y-m-d', strtotime('-' . $how_long_days . ' days')) . '\'";');

		add_filter( 'posts_where', $filter_where );

		foreach ($blogs as $blog) {
			switch_to_blog( absint($blog) );

			$recentQuery = new WP_Query();

			$recentQuery = get_posts( $args );

			foreach ( $recentQuery as $post ) {

				$recentPosts[] = array(
					'blog' 		=> $blog,
					'post' 		=> $post->ID,
					'post_date' 	=> $post->post_date,
					'post_modified'	=> $post->post_modified,
					'post_title' 	=> $post->post_title,
					'comment_count'	=> $post->comment_count
					);
			}

			wp_reset_query();

			restore_current_blog();

		}

		remove_filter( 'posts_where', $filter_where );

		/* Sort posts by field and trim to the requested number of posts */
		foreach ($recentPosts as $key => $row) {
		$sortkey[$key]  = $row[$sort_by];
		}

		array_multisort($sortkey, $sort_order, $recentPosts);

		return array_slice( $recentPosts, 0, $how_many );
	}

}

?>

		<div id="primary">
			<div id="content" role="main">

				<?php the_post(); ?>

				<?php get_template_part( 'content', 'page' ); ?>

				<?php if ( function_exists('wpms_latest_post') ) {
					$query = wpms_latest_post();

				 if ( !empty( $query )) { ?>

							<?php /* Start the Loop */ ?>
							<?php foreach ( $query as $netpost ) { 

								switch_to_blog( $netpost['blog'] );

								query_posts ( 'p=' . $netpost['post'] );

								if ( have_posts() ) {

									the_post();

									get_template_part( 'content', get_post_format() );

									}

								wp_reset_query();

								restore_current_blog(); 

								} ?>

						<?php }
					} ?>

				<?php comments_template( '', true ); ?>

			</div><!-- #content -->
		</div><!-- #primary -->

<?php get_footer(); ?>

Etichete: ,

« Înregistrări mai vechi

Articole recomandate