
Using component sh40SEF
Foreword :
All information below is based on Joomla! 1.0.x version. It is can be used for Joomla 1.5 plugins, however url samples
should be adjusted to match those of the Joomla 1.5 non-sef urls.
A - Background
sh40SEF builds and manages SEF URL for the Joomla! CMS. It uses a plugin system to adapt to various components.
sh404SEF is used in two ways : to "create" URL and to "revert" URL.
1 - Creating URL
Creating a SEF URL is the process of finding a SEF counterpart to one of Joomla! classical non-sef URL. As an
example :
non-sef URL = index.php?option=com_content&task=view&id=24&Itemid=3
SEF URL = /News-section/Fun-category/what-is-the-difference-between-a-pigeon.html
It is up to each component to trigger this process, as it not automatic. Before using any URL, a component should call
Joomla! sefRelToAbs() (resp: JRoute:_() for Joomla 1.5) function, passing the non-sef URL as a parameter. The returned
value is the SEF URL calculated for the non-sef value passed.
However, Joomla! built in sefRelToAbs() (resp: JRoute:_()) function is effective but limited. It produces URL similar to :
/option,xxx/task,zzz....(resp: improved in Joomla 1.5) sh404SEF role is to build up a more significative URL, starting from
the same initial data : the non-sef URL.
As said before, sh404SEF uses a plugin system. It provides a framework for handling the URL themselves, storing them
in DB, retrieving them upon request, but depending on the com_xxxx part of the non-sef URL, it calls upon a dedicated
php file to work out the details of building the SEF URL. These "plugins" can be either "native" or "foreign":
Native plugins have been designed and written specifically for sh404SEF, and take full advantage of its features. Native
plugins either comes with sh404SEF (Joomla! core such as com_content, com_newsfeeds, com_search, com_poll,...,
popular components such as Docman, Fireboard, Virtuemart, Community Builder,...), or can be packaged with their
components by components authors.
Foreign plugins have been designed for popular SEF components such as OpenSEF and SEF Advanced. They usually
come with the components itself (components such as Sobi2, Alphacontent, ... come with these plugins). They are stored
in the component own directory, and usually take the form of a single file : sef_ext.php. Usually, sh404SEF can use
these plugins automatically and transparently, even though some compatibility issues may arise on some occasions. If
both a native and a foreign plugin exist for a given component, sh404SEF backend parameters allow you to decide which
one should be used ("Override own sef_ext").
extensions.Siliana.com
http://extensions.siliana.com Powered by Joomla! Generated: 28 May, 2009, 04:44
After being calculated, each SEF URL is stored in Joomla! database, together with its non-sef counterpart, in order to
avoid this time consuming process next time the same URL is requested.
Note : in addition to writing the URL to the database, sh404SEF has a cache system to speed up the retrieval process.
Both writing to the database and to the cache is part of sh404SEF framework, and therefore component developers
willing to write a sh404SEF native plugin can focus only on building up the URL as they wish.
Writing native plugins is the main topic of the remaining of this document.
2 - Reverting URL
When Joomla! receives a request to serve a page, it passes on the requested URL to sh404SEF, which looks up the
database to try find a record that matches the request. If a SEF match is found, then sh404SEF returns the non-sef
(index.php?option=com_xxx&task=zzz...) part of the record URL for further processing. This process is called "reverting"
the URL. It is needed because Joomla! does not know anything about SEF URL, and can only process non-sef URL.
Reverting URL is totally automatic with sh404SEF. In other words, and contrary to foreign plugins, there is no code to
write in order to "decode" the SEF URL and turn it back into a non-sef URL.
B - Directory layout and names
It follows from paragraph A that 3 types of plugins can co-exists. They can be in 3 locations :
- foreign plugins are located in /components/com_component_name
- native plugins delivered with sh404SEF are in /components/com_sef/sef_ext/ (resp:
/components/com_sh404sef/sef_ext)
- individual native plugins can be in /components/com_component_name/sef_ext
Native plugins have the same name as the component they work for.
For instance, assuming that we have written a nice component called HeyJoe, and that we have also produced a
sh404SEF native plugin for com_HeyJoe, then main plugin file will be :
/components/com_HeyJoe/sef_ext/com_HeyJoe.php
You can make use of any other file you like, like languages files for instance, but it is up to the component author to
manage these additional files.
Note: it may happen than sh404SEF does have a native plugin for a component, but this component also comes with a
plugin for sh404SEF. In such event, then the component plugin will be used instead of sh404SEF own plugin.
extensions.Siliana.com
http://extensions.siliana.com Powered by Joomla! Generated: 28 May, 2009, 04:44
C - Writing a sh404SEF plugin
1 - Plugin anatomy
As said before, a native plugin has a main file called com_component_name.php. A sample plugin file is supplied with
sh404SEF. It is named "sample_com_plugin.php", and resides in the /components/com_sef/sef_ext (resp.
/components/com_sh404sef/sef_ext) directory. It is made up of 3 main parts :
a - Initialization section
This part simply calls a sh404SEF initialization function, and also set or reset some variables. It should not be modified,
unless you know what you are doing. The initiliazation code is :
// ------------------ standard plugin initialize function - don't change ---------------------------
global $sh_LANG, $sefConfig;
$shLangName = '';;
$shLangIso = '';
$title = array();
$shItemidString = '';
$dosef = shInitializePlugin( $lang, $shLangName, $shLangIso, $option);
// ------------------ standard plugin initialize function - don't change ---------------------------
You may not be using different languages in your component. However, sh404SEF has been designed from start with
handling multi-lingual sites in mind. Specifically, this part "discovers" the non-sef URL language, taking into account the
Translate URL and InsertLanguageCode parameters that can be set in sh404SEF backend.
b - main URL build up
This part is what a component author has to write, defining how URL should be build according to the inner working of its
component. This is done by filling up an array called $title. Each element of the URL is simply added to the array, in the
same order it should appear in the final URL. Later on sh404SEF will process this array to produce the final URL.
Additionnaly, sh404SEF provides a mechanism by which you can decide to leave some URL variables (GET params) as
part of the "query string" instead. For instance, let's look at this non-sef URL :
http://mydomain.com/index.php?option=myComponent&task=viewUserDetails &userId=2456&Itemid=23
You can either decide to turn it into fully SEF urls such as:
htpp://mydomain.com/This-is-my-User-name/View-user-details.html
extensions.Siliana.com
http://extensions.siliana.com Powered by Joomla! Generated: 28 May, 2009, 04:44
or instead have a partially SEF URL such as :
htpp://mydomain.com/View-user-details.html?userId=2456
This is a good solution in cases where having all URL turned fully SEF-ied would generate large quantities of records in
the database, without adding value in terms of search engine optimisation. A few examples are :
* a component handling users. There might be a link to view details, to update user record, to delete user, to print,
export, etc for each individual users. That's fine with a few tens of users, maybe with a few hundreds, but if you plan on
having several thousands users, then it is probably better to leave user identification as a GET variable instead of turning
the id into a user name
* limit and limitstart variables are used by Joomla! to handling multipage. Again, with a large number of articles or items
to show (hundreds, thousands), this may generate excessive space consumption in the database
* if you have a search feature using GET variables, then it is better to leave the search word out of the SEF url, or else
any word searched by a user will generate a unique URL record in the database.
Generally speaking, it is suggested that parameters not conveying any meaning be left out of the text part of the URL, at
least if a large number of them is expected. Make sure you don't take any risk there. It is important to decide early on
what your SEF URL will look. A good thing is also to provide users with the ability to change the URL format, according to
their specific need, site size, etc. At the moment, sh404SEF does not provide a facility to integrate parameters for plugins
other than those supplied with sh404SEF. So if you add user defined parameters, you have to do so in your own control
panel.
c - Finalization section
This part calls a sh404SEF function. Again you should not change it, unless you want to do something specific. You may
for instance do something special in case $dosef is false, that is you have decided for some reason no to build a real
SEF URL.
The finalization code is :
// ------------------ standard plugin finalize function - don't change ---------------------------
if ($dosef){
$string = shFinalizePlugin( $string, $title, $shAppendString, $shItemidString,
(isset($limit) ? @$limit : null), (isset($limitstart) ? @$limitstart : null),
(isset($shLangName) ? @$shLangName : null));
}
// ------------------ standard plugin finalize function - don't change ---------------------------
2 - Building up the SEF URL
extensions.Siliana.com
http://extensions.siliana.com Powered by Joomla! Generated: 28 May, 2009, 04:44
A few important things to know :
* you only have to build up the SEF URL part after the domain name. For instance, if you whish to produce a URL like :
http://www.mysite.com/product-infos/giant-cliffhanger/
then you only have to include in your plugin :
$title[] = 'product-infos';
$title[] = 'giant-cliffhanger';
* all parameters contained in the non-sef URL have already been extracted, and are available in the plugin file context.
For instance, you can directly use something like :
if (isset($task))
$title[] = $task;
if the non-sef URL contains : ...&task=view..., then the resulting URL will contain : /view/
Please test variable existence using isset() or empty() before using a variable. We have found that many people run their
server with NOTICE errors showing. As sh404SEF may be called before headers are output by Joomla!, having a
NOTICE error displayed will break everything and will totally prevent to page to being displayed.
* sh404SEF defaults to leaving each parameter as a GET param. You have to specifically tell sh404SEF that a variable
has been turned into its SEF equivalent, or is not required. You do this by calling shRemoveFromGETVarsList() function.
For instance, if you have a GET param like : ...&task=viewUserDetails....
and you have decided to insert in the SEF URL a meaningfull string such as : .../View-user-Details/... instead. You'll do
the following :
if (isset($task) &&($task == 'viewUserDetails')) {
$title[] = 'View-user-Details';
shRemoveFromGETVarsList('task');
}
extensions.Siliana.com
http://extensions.siliana.com Powered by Joomla! Generated: 28 May, 2009, 04:44
which can be understood as :
If $task is View user details
1 - insert appropriate text in URL
2 - tell sh404SEF to not add $task to URL anymore
If 2 is missing, then the SEF URL will have an added part : ?task=viewUserDetails. This will actually not cause any
issues, and will not prevent Joomla! operation
Most plugins should be fine having this somewhere in their code :
shRemoveFromGETVarsList('option');
shRemoveFromGETVarsList('lang');
if (!empty($Itemid))
shRemoveFromGETVarsList('Itemid');
// optional removal of limit and limitstart
if (!empty($limit)) // use empty to test $limit as $limit is not allowed to be zero
shRemoveFromGETVarsList('limit');
if (isset($limitstart)) // use isset to test $limitstart, as it can be zero
shRemoveFromGETVarsList('limitstart');
* all cleaning up, url encoding, characters replacement, etc is done automatically by sh404SEF. You don't need to do it
yourself. Just add the text you want to appear, straight from the database if you whish.
* you should not insert yourself a language code in the SEF URL. This is handled automatically by sh404SEF, again
taking into account users defined backend parameters.
* if you are using title as a parameter in your URL, then this would interfere with the $title array. To prevent this issue, the
content, if any, of ...&title=.... has been stored in : $sh404SEF_title variable.
You should use $sh404SEF_title instead of $title to build the URL
* do not add intermediate slashes, they'll be added automatically later on. However, the last element in the URL (ie. the
last element in $title) can be a /. If so, the final URL will end with a slash. If the last element is anything else than a /, then
a suffix will possibly be added. Users can set up a suffix in sh404SEF backend (such as .html for instance), and they can
turn this feature on/off as they wish. Suffix being appended is also automatic.
extensions.Siliana.com
http://extensions.siliana.com Powered by Joomla! Generated: 28 May, 2009, 04:44
* anywhere in the plugin you can set $dosef to false; this will force the URL back to non-sef. It can be used for instance if
some specific URL are too complicated or too numerous to justify a SEF version.
* Utility function : getMenuTitle()
This function will return the menu item title corresponding to either an option (option=com_content for instance) or Itemid,
combined with language information.
It can be called by :
$title[] = getMenuTitle($option, (isset($task) ? @$task : null), $shCurrentItemid, null, $shLangName );
$option is always available, it is the component name (com_HeyJoe for instance)
$task may or may not exists, according to your component operation
$shCurrentItemid is always available. It is set by sh404SEF and contains the current page Itemid. Just remember that
your plugin is being called upon normally, as part of sefRelToaAbs(), when Joomla! is preparing the content of a page
and needs to SEF-y all links on this page. $shCurrentItemid is this page Itemid.
You don't have to use shCurrentItemid as, due to the way your component operates, you may already one what is the
Itemid of the menu element you want to use. Just replace $shCurrentItemid by your own Itemid.
$shLangName is needed to handle tranlsation or not, it is automatically set within the Initialization section of the plugin,
as seen before
* Utility function : getContentTitles()
This function uses pretty much the same parameters as the previous one. It will return a regular content element title.
It can be called by :
$title[] = sef_404::getContentTitles($task,$id,$Itemid, $shLangName)
(please make sure $task and $id exist before using them)
$task can be 'section', 'category', 'blogsection', 'blogcategory' or 'view'.
$id is the section, category or content element id. If $id is set, then the corresponding section, category or element title
extensions.Siliana.com
http://extensions.siliana.com Powered by Joomla! Generated: 28 May, 2009, 04:44
will be fetched from database and returned (alias can be returned for content elements, according to sh404SEF backend
params). If no $id is passed to the function, then it will return the menu element title instead (internally using
getMenuTitle())
3 - Working with multiple languages
URL in sh404SEF sites have two parts: some URL elements are constant, and some are variables.
Constant elements are things like : .../view-products-details or /Delete-product
Variable elements are things like : .../pet-mammoth-clothing
"Delete-product" is a fixed text string that describe an action for instance, whereas "pet-mammoth-clothing" is fetched
from the database. It can be a product name in Virtuemart, or a content title.
Constant elements are translated through a set of language strings that should be supplied with the plugin, either inside
the plugin, or as a separate text file. Beware that all translation strings must be available at anytime, as a single web
page may have URL in several languages at the same time. Plugins delivered with sh404SEF use a global variable
called $sh_LANG. It is a two-dimensionnal array, indexed on language iso code and string ID. For instance :
$sh_LANG['fr']['_SH404SEF_FB_SHOW_USER_PROFILE'] = 'Voir vos informations utilisateur';
$sh_LANG['en']['_SH404SEF_FB_SHOW_USER_PROFILE'] = 'View user information';
When using such an array, you can make use of two variables, which are initialized with the appropriate values in the
initialization section of the plugin :
$shLangName : contains the URL language name ("french", "english", "spanish")
$shLangIso : contains the URL language short iso code ("fr", "en", "es")
So you would use :
$title[] = $sh_LANG[$shLangIso]['_SH404SEF_FB_SHOW_USER_PROFILE']
Variable elements are translated using Joomfish. Because URL translation can be switched on or off, on a component by
component basis by the user, it is recommanded to use the following code whenever fetching any data that can be
translated from the database :
if (shTranslateUrl($option, $shLangName))
$database->loadObject( $sectionTitle);
else $database->loadObject( $sectionTitle, false);
extensions.Siliana.com
http://extensions.siliana.com Powered by Joomla! Generated: 28 May, 2009, 04:44
shTranslateUrl() will return true if URL for the component "$option" should be translated, and false otherwise.
shTranslateUrl() reads the user set backend parameters to decide about this. It will also always return false if Joomfish is
not installed, therefore this syntax will work in any situation. When Joomfish is installed, each classical Joomla! database
object function can be called with a second parameter to force translation on or off.
Warning : for Joomfish to operate and perform translation, you MUST include the table id in the select clause of your
query! For instance :
"SELECT name FROM #__contents WHERE id=3" will NEVER be translated.
To allow translation, query has to be :
"SELECT id, name FROM #__contents WHERE id=3"
With this last query :
$database->loadObject( $sectionTitle); will return the translated value of 'name'
$database->loadObject( $sectionTitle, false); will return the original value of 'name' (ie its value in the site default
language)
Note : remember to explicitly remove the $lang variable from the URL (using shRemoveFromGETVarsList('lang')),
otherwise it will show up in the final URL as a query string bit (...&lang=xx...)
extensions.Siliana.com
http://extensions.siliana.com Powered by Joomla! Generated: 28 May, 2009, 04:44
Bạn đang đọc truyện trên: Truyen247.Pro