Update 51 (2014.05.01)

Post Reply
Site Admin
Posts: 34018
Joined: Wed Sep 10, 2008 11:43 am

Update 51 (2014.05.01)

Post by admin »

[news_title]Multilingual Sites, Separate tags and more[/news_title]

Update 51

Multilingual Sites

This is the way to create fully functional translation for all descriptions (galleries, categories, tags and so on) at your site. You can translate interface of your site using anyversion of script [[New Rotation Hints]] (i18) but with 51 you can translate your content.

First, go to rotation - settings - Multilingual and create as many languages as you need. Once it's done you'll be able to edit descriptions of all categories and galleries in all languages you've setup. But in most case you'd like to do it automatically. You can use [[Google translate]] for it.

So let's say we have main language 'English' and 2 translations : de and es.

You can switch language by adding to url &force_lng=... (add 'de' or 'es' for our example).

There are 2 options how to display appropriate translation and so there are 2 options in rotation - settings - Multilingual

1. When we have the URL but texts are in different languages based on browser language (Auto Switch language)

2. When we have different URL and texts are shown based on URL, not browser language - Auto redirect to existing language

Auto Switch language

Script searches for a language code in request headers and shows a page based on that language. URL is not changed. Everything's straight forward - the option is switched on - script shows the same page with different texts based on language.

Auto redirect to existing language

You can see an option called 'Auto redirect to existing language' that redirects a surfer to a page based on his language, default is


ie if we get a request for http://domain/category/asd/ but we have 'de' translation AND request has 'de' as a browser language , user will be redirected to http://domain/ru/category/asd/

To make this work you have to add to .htaccess.

Code: Select all

RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]{2})/(.*)$ $2?%{QUERY_STRING}&force_lng=$1 
This is just an example, of course you can have your own URLs

Translation stats

There are a couple of ways to count thumb stats for different languages: Own category stats and Own thumb stats.

If both options are off - you just have a translation of your site.

Own category stats - yes, means we have separate stats for category thumbs, this is probably a useful one. The reason is that if you a multiniche site for Japanese traffic you probably want a thumb for japanese category to be at the top of your index page and so on for other countries. Caz of course there are some discrepancies in preferences for different nations.

Own thumb stats all thumbs will have it's own stat for each language.

Separate tags

And separate tags for each slave\language. Basically you can think about new language as a new slave site.
This is probably a bit difficult part here.

So each slave can have it's own tags. Why would you need it? let' say you add a gallery with description 'word1', that has been changed to 'word2' for a slave. Before version 51 you'd have 'word1' as a tag for a slave , so http://slave/?tag=word1 would show galleries with 'word2'

There are 2 things you should think about here. When each slave has it's own tags - DB grows. Sometimes you actually fine with http://slave/?tag=word1 showing galleries with 'word2'. But this might bring some extra SE traffic. No one knows for sure, but you can try.

The options in is Rotation - Settings - test, and it's off by default.

We have to receive some feedback from users about it.

Sphinx 51

There are some changes for sphinx.conf with version 51 as we have language slaves and we can also refine search results.

Before 51 if you did a search like ?search=...&group_id=... it would search using tag main group only, if you want to search using ext group set you have to change sphinx config a bit

Code: Select all


source scj
	type					= mysql

	sql_host				=  ............
	sql_user				=  .............
	sql_pass				=  ..............
	sql_db					=  ..............
	sql_port				= 3306	# optional, default is 3306

	sql_query				= SELECT id, crc32(g.gallery_md5) as gallery_md5_crc,  UNIX_TIMESTAMP(activation_date) as date, tags, alt, description, duration, sponsor_id, rgroup, gs.total_ctr, \
							  g.content_type, (SELECT group_concat(group_id) FROM rot_gal2group as g2gr WHERE g2gr.gal_id = g.id) as categories FROM rot_galleries as g JOIN rot_gallery_stats AS gs ON g.id = gs.thumb_id \
							  JOIN rot_gallery_info AS gi ON g.gallery_md5 = gi.gallery_md5 \
							  JOIN rot_gallery_data AS gd ON g.gallery_md5 = gd.gallery_md5 \
							  WHERE status = 1 and gs.best_thumb = 'yes' and rgroup != 0 and gs.group_id = 0
	sql_attr_timestamp		= date
	sql_attr_uint		    = duration
	sql_attr_uint		    = sponsor_id
	sql_attr_uint		    = rgroup
	sql_attr_float		    = total_ctr
	sql_attr_uint		    = content_type
	sql_attr_uint			= gallery_md5_crc
    sql_attr_multi 			= uint categories from field; 

	sql_query_info			= SELECT * FROM rot_galleries WHERE id=$id


Multilingual Sites & Sphinx

If you have several translations or just slaves with separated descriptions, it's a good idea to have a separate sphinx index for it. Ie Let's say gallery id 12345 has a description 'word1' and slave has this gallery with description 'word2'. If we have just 1 index for master and slave and surfer does a search at slave for 'word1' - master's index will be used and will find that gallery 12345, and script will show this gallery using it's description for this slave = "word2"

You can click 'Generate spinx' near each slave.

Separate Thumb 2 Group Stats

Before 51 and actually in 51 too for back compatibility each thumb has just 1 CTR even if it belongs to more then 1 category. Now you can have a separate CTR for each group.

But there are a couple of things to consider before doing it.
1. You'll need more 'shows' to rotate it , ie if each thumb has just 1 group and 'new thumb live time' = 300, you need 300 'shows' to 'cast\test' that thumb. If you have 'separate stats' on and a thumbs belongs to 5 groups - you need 300 * 5 = 1500 'shows'

2. It add more data to your data, because we have to store that data.

On the other hand this might lift up productivity.
thumb fixed_num

A new parameter for <thumb - fixed_num

here's an example

<thumb num=1-10 fixed_num=true> bla-bla </thumb>

and it's used to fix thumbs. ie if you have num=1-10 so at first page you see thumbs 1-10, at second - 11-20 and so on. If you want to see exactly 1-10 att all pages - use this new parameter.
thumb adjust_num_to_page

In contrast to a tag described above, here's an example.

<model num=1-10

shows 10 first models at all pages

<model num=1-10 adjust_num_to_page=true

will output 1-10 at the first page, 11-20 and the second an so on.

Also useful for <banner num=1 ...
Category All

Now you can create a pseudo category All (you have to name category exactly like this) so you can use all the variables that each category has for likes like /category/All/ (of course if you have such links)

That's useful for multilanguage sites to have description for categories in different languages.

A new tag, that may be not really useful but there were a couple of requests asking for it so here it is.


basically it just pases this code

Code: Select all

<script language='JavaScript' type='text/javascript'>
   document.write ("<" + "img alt='' border=0 width=0 height=0 style='position: absolute; top: -100; left: -100' src='");
   document.write ('/scj/cgi/rot_in.php?crc=<!--PAGE_CRC-->');
   if (document.referrer)
      document.write ("&referer=" + escape(document.referrer));
   document.write ("'>");

Why this way? Script counts shows for thumbs when user loads that rot_in.php, so this way rot_in can be loaded only if user's browser executes JS. So in someway it's an anticheat feature.


The "Next generation" of previous tag is


that actually does the same at the tag above and rot_in.php at all - counts +1 'show' for thumbs

But there are some discrepancies with rot_in.php

* rot_in stays in html and is loaded by browser, is a browser does not load images - it won't be loaded and +1 won't be added to images' shows. <!--SCJ_COUNT_VIEWS--> is processed by server and doesn't appear in html but +1 added to shows even if browser doesn't load images.
* If you use JS code ot tag aboму to load rot_in.php for browsers with JS only - shows will be counted for browsers with JS+images only, <!--SCJ_COUNT_VIEWS--> always adds shows

Some people think that this way is better for SEO.

Related Galleries : All Tags

A new option to search Related galleries based in all tags.

before that we selected just 1 tag, now you can select galleries with closest tag coincidence. Should be good.

Slave Synonimization

Now use can setup different synonimization settings for each slave.
All theese settings for slaves can be found in master's Rotation Settings.
Sphinx for slaves

Note that you can setup different sphinx index for each slave.
Template Search&Replace

You can search and replace some code in all templates and even at all sites of your network.
Model Data

До версии 51 описания моделей были не разделены для слейвов и мастера. В 51 слейвы могут иметь собственные описания для моделей.

Model Alias

A new field for models: you can setup aliases for models to raise model detection rate.

Ie if you have a description 'some scene with Alice' and you have a model Alice - script will assign this model for that gallery. But if description is 'some scene with Alisse', it won't. Even if you know and Alisse and Alice are the same actor. So you can add an alias for Alice.

You can create extra thumbs even if you didn't do that during import.

cd ....scj/bin
php rot.php action=create_extra_thumbs extra_thumb=2 crop_profile=default

where extra_thumb= can be 1,2 or 3, and crop_profile= is crop profile name.


If you have rating at your pages you can output how many votes a gallery has with each rating.

For example,

<!--RATING_1--> - how many users voted 1,
<!--RATING_2--> - how many users voted 2,

and so on


A new tag for Import Replacements. If you import for example some embeded content you get a code width="..." height="..." with various height and width

You can replace those values with some fixed size to fit your design

Code: Select all

If this field 	 - URL , for example 
Contains this value 	xhamster or just *
Then Search For 	width="<!--ANY_VALUE-->" height="<!--ANY_VALUE-->"
in This Field 	Embed Code
And Replace it With    width="400" height="300"

A new pagination. There are some requests to change pagination and we try to implement it, but as a new tag, to keep <navigation tag as is.

Code: Select all

<pagination first_pages=3 adjustment=1 last_pages=3 range_separator="...">

Model pagination

Pagination for models if you have a lot of models for to display at one page

This code will output the same set of 10 model t each page.

Code: Select all


<models num=1-10>
<!--MODEL_NAME--> <br>

To show different sets for each page

Code: Select all


<models num=1-10 [b] adjust_num_to_page=true [/b]>
<!--MODEL_NAME--> <br>


now we need pagination for it

Code: Select all

<models type=pagination items_per_page=10 first_pages=3 adjustment=1 last_pages=3 range_separator="...">
Notice type=pagination here. It means 'output' pagination here, not models. Looks like this the closest option that fits current tag systems.

We need your feedback on this )


Let's say you have ImportSet with descriptions only. But you get more SE traffic you'd like to add some relevant words based on synonimization to some places in gallery template. To do it you'd like to have synomized description in alt or custom var, for example.

Here's how to do it:

1. Switch off synonimization
2. Add 2 rules to Import Replacements

First, copy description to alt ot custom var.
Second, replace * for this field (alt or custom var) with {SYNONIMIZE}

This way it won't changed original description and you'll get a synonimized description in alt\custom var to use in your template.

Tag prefix

There are some functions you'd like to apply to your tags and you can do it in templates with php , for example you'd like to escape all quotes in tag. You can do it in template like

Code: Select all

$myvar =  <<<EOB
echo addslashes($myvar);
this adds a bunch of code and template doesn't look nice. That's why tag prefixes where added.

For example, <!--ALT--> becomes <!--ESCAPED_ALT--> and the same way it can be added to any tag

At present moment we have following tag prefixes

1. Quote string with slashes

<!--ALT--> becodes <!--ESCAPED_ALT-->

2. HTMLENTITY Convert all applicable characters to HTML entities

Code: Select all

'&' (ampersand) becomes '&' 
'"' (double quote) becomes '"' when ENT_NOQUOTES is not set. 
''' (single quote) becomes ''' only when ENT_QUOTES is set. 
'<' (less than) becomes '<' 
'>' (greater than) becomes '>' 

  <!--ALT--> becomes <!--HTMLENTITY_ALT--> 
3. URLENCODE URL-encodes string

Code: Select all

  <!--TAG_1--> becomes <!--HTMLENTITY_TAG_1--> 

4. RAWURLENCODE to replace special symbols in URLS

Code: Select all

  An example: <!--TAG_1--> becomes <!--RAWURLENCODE_TAG_1--> and so on


5. STRIP_SPECIAL_CHARS_ to delete all special symbols like !$@ and so on

Actuall code is trim(preg_replace('|[\\\,\|\,<\.>\/\?;:\'\"\[\{\]\}\`~@#\$%\^&\*\(\)\-_=\+]*|i', "", $var))



New tag <!--GET.. as an array of GET vars, for example if you pass ?search=... to script it will be available as

You can also add tag prefixes here, for example, <!--ESCAPED_ + GET


Show only active tags

As you probably know tags have statuses and for tag could we use only active tags. But when we output actual gallery - we display all gallery tags. Now there's an option to display only active tags at gallery's page too. Нou can switch it on and off any time. When you display active tags only it doesn't delete the rest of the tags from DB. So you can switch back to normal at any time, but this feature does not cut your DB.

If you want to have less tags in DB - use white tag list got example.

Search queries log type

When a user does a search at a site - that request is being logged and script keeps log for "History max length, days". So we actually have a log of recent requests, but it takes a bit more space it DB. Ie if we had a search 'word1' yesterday and today - that's gonna be 2 records. if you switch log type to 'total' - that's gonna be just 1 record, be in this case it will show search requests during all the time of site existence.

Template Cache time

You can setup personal Cache Time for each template. 0 means use Rotation - Settings.

Note, that if you due to some reasons what to set personal cache time for each template based on some other conditions you can do it in common.php

Code: Select all


if (your condition) { 
define('CACHE_TIME', 200);
} elseif (another condition) {
define('CACHE_TIME', 100);

if (!defined('CACHE_TIME')) define('CACHE_TIME', 900);


Based on logged searches

You can add 'suggested searches' so when user starts to type something in a search field you'll show him similar requests

Addings JS and styles to template

Code: Select all


<script type="text/javascript" src="/scj/includes/js/jquery.js"></script> Это может быть уже и есть в странице.
<script type="text/javascript" src="/scj/includes/js/jquery.autocomplete.min.js"></script>

	        serviceUrl: '/scj/tube/index.php?force_template=search_suggest',

    	        onSelect: function(suggestion, data) {


Code: Select all

.autocomplete-suggestions { border: 1px solid #999; background: #FFF; cursor: default; overflow: auto; }
.autocomplete-suggestion { padding: 2px 5px; white-space: nowrap; overflow: hidden; }
.autocomplete-selected { background: #F0F0F0; }
.autocomplete-suggestions strong { font-weight: normal; color: #3399FF; }

and a search field

Code: Select all

<input class=inputbox value='' type="text" size="30" id="search_field"> <br>
You can notice that script requests template 'search_suggest'. Here it is

Code: Select all

header('Content-Type: application/xml');

<thumb search_log=all num=1-10 skip_search_log=true search=GET_QUERY>

As you can see it is a regular template with a couple of new things like header -application/xml
and a tag prefix <!--ESCAPED_ that has been described here already.

Based on regular search

You can also suggest results based on existing galleries. Basically it's pretty much the same


Code: Select all

.autocomplete-suggestions { border: 1px solid #999; background: #FFF; cursor: default; overflow: auto; }
.autocomplete-suggestion { padding: 2px 5px; white-space: nowrap; overflow: hidden; }
.autocomplete-selected { background: #F0F0F0; }
.autocomplete-suggestions strong { font-weight: normal; color: #3399FF; }

a field

Code: Select all

<input class=inputbox value='' type="text" size="30" id="search_field"> <br>

JS code

Code: Select all

<script type="text/javascript" src="/scj/includes/js/jquery.js"></script>
<script type="text/javascript" src="/scj/includes/js/jquery.autocomplete.min.js"></script>
	        serviceUrl: '/scj/tube/index.php?force_template=gallery_search_suggest',

    	    onSelect: function(suggestion, data) {
                location.href = suggestion.data;



Another template, let's call it 'gallery_search_suggest'

Code: Select all

header('Content-Type: application/xml');

<thumb skip_search_log=true search=GET_QUERY num=1-10>



Trade Landing page

You can see landing pages in Stats for each trade. In most case you'd want this information for SE, but it might be worth checking for regular traders too.

Group trade exout

Up till version 51 if you link like out.php?group=.. and a surfer had visited all traders in this group - he would be sent to a trader from any other group.

Now you can finetune it in Settings - If group is indicated and there's no trades left in group send to ...

Trade Poke

A new feature to try to start old trades. Check CJ Settings - Other.

An example: trader doesn't send you hit, you don't send him. May be if you try to send him some he'll send some in return. So here's a way to do it automatically.

If trader has less then X hits but at the same time has good Alexa rating (and traffic) - try to send hit some hits (Percent of out traffic to send ). Script will try to start a trade with all traders one by one.

Cookie Engine

Usually script saves some information in cookies, and cookie names are the same for all domains.

Now there are 2 new ways to do it. Check Settings - other - Cache Engine.

if you have it as md5 - cookie names will be encoded with md5 and will be unique for each domain.

'Cache' engine means that we won't use a regular cookie, instead we'll save all the information locally and in cache. Ii is recommended to use new cache engines (like Redis, Couchbase, memcache) in this case because file cache is a bit slow here.


Did you know that if you have a select box, you can select more then 1 item if you hold Ctrl while clicking? It's standard browser's feature.


Update 51 released !

New features: Multilingual Sites, Separate tags and more[/scj_title]
Have you done script update ?

Post Reply