hi all;
in the demo site changes are:
1- form submition: post and get, try a search for get method and post a news for post method ( you can login using: demo,demo)
2- some redirections, sorry I was unable to do this from whithin the theme, so I made some changes to some files!
3- now you can use inline debug mode and view the resualts in the page. I will set the debug mod so you can test it. the great thing is that we can put the comment: <!--{xo-logger-output}--> in the out put and the debug data will be replaced by this comment.
4- getting left blocks on each request. so whene you go to the news module the block will show you extra menu items.
on theme.html top, now we have:
le="color: #000000"><?php <{php}> if(isset($_GET['ajaxpage']) || isset($_POST['ajaxpage'])){ header("Content-type: text/xml; charset=UTF-8"); echo '<?xml version="1.0" encoding="utf-8"?>'; if(isset($_GET['leftBlocks']) || isset($_POST['leftBlocks'])){ echo '<ajax-response>'; echo '<response type="object" id="blocks">'; $sid = 1; $title = "title"; $content = "Block Content!!"; echo '<blocks sid="leftBlocks">'; foreach($this->_tpl_vars['xoops_lblocks'] as $block){ echo '<block bid="" title="'.$block['title'].'" module="">'; echo '<content>'; echo '<![CDATA['.$block['content'].']]>'; echo '</content>'; echo '</block>'; } echo '</blocks>'; echo '<dbug>'; echo '<![CDATA['; <{/php}> <!--{xo-logger-output}--> <{php}> echo ']]>'; echo '</dbug>'; echo '</response>'; echo '</ajax-response>'; }else{ //echo '<!ATTLIST page content CDATA #IMPLIED>'; echo '<ajax-response>'; echo '<response type="object" id="page">'; global $xoopsOption, $xoopsConfig, $xoopsModule, $xoopsRequestUri; $url = str_replace('?ajaxpage=1','?',($_SERVER['HTTP_HOST'].$xoopsRequestUri)); $url = str_replace('&ajaxpage=1','',$url); $url = str_replace('?_=','?',$url); $url = str_replace('&_=','',$url); $url = str_replace('_=','',$url); $url = urlencode($url); if($xoopsModule){ $module = $xoopsModule->getVar('dirname'); }else{ $module = '_nomodule_'; } //$title = "page title"; $title = $this->_tpl_vars['xoops_sitename'] . ' - ' . $this->_tpl_vars['xoops_pagetitle']; echo '<page url="'.$url.'" title="'.$title.'" module="'.$module.'" time="" href="">'; echo '<content>'; echo '<![CDATA['.$this->_tpl_vars['xoops_module_header'].$this->_tpl_vars['xoops_contents'].']]>'; echo '</content>'; echo '<dbug url="'.$url.'">'; echo '<![CDATA['; <{/php}> <!--{xo-logger-output}--> <{php}> echo ']]>'; echo '</dbug>'; echo '</page>'; //echo '<page url="'.$url.'" title="'.$title.'" content="content" />'; echo '</response>'; echo '</ajax-response>'; } }else{ <{/php}>
the javascript to handle this is:
le="color: #000000"><?php <script type="text/javascript" src="<{$xoops_imageurl}>Rico/prototype.js"></script> <script type="text/javascript" src="<{$xoops_imageurl}>Rico/rico.js"></script> <script language="javascript"> /* * * farshid: * function sanitizeATags * called when ever we need to make <a> tags call rico functions * 1- create and attach proper onClick attribute * 2- remove the href * 3- some criteria should exict as we need some links not vhanged (ex. <{$xoops_url}>/admin.php) * */ function sanitizeATags(){ /* * get all <a> tags and put them in atags variable */ atags = document.getElementsByTagName('a'); /* * run throgh all atags, first we will check these: * atags[i].href != '' a element is linked to somewhere * atags[i].href.indexOf('admin') == -1 skip admin link(s) * atags[i].target != '_blank' skip links that will open in new window (ex. banners) * atags[i].href.indexOf('<{$xoops_url}>') == 0 href attribute starts with our site url * */ for(var i = 0; i < atags.length; i++){ if((atags[i].href != '') && (atags[i].href.indexOf('admin') == -1) && (atags[i].target != '_blank') && (atags[i].href.indexOf('<{$xoops_url}>') == 0)){ /* * * create an onClick attribute, set ints value to the proper function call: getPage(url) * the url comes from atag href attribute. * after creating it we will append it to the <a> element and set the href attribute: javascript:void(0); * this will disable the link from going anywhere. * * NOTICE: setAttributeNode is not supported in explorer. * */ onClickAttribut = document.createAttribute("onClick"); onClickAttribut.nodeValue = "getPage('"+atags[i].href+"');"; atags[i].setAttributeNode(onClickAttribut); //atags[i].setAttribute(onClickAttribut); atags[i].href = "javascript:void(0);"; } } } /* * * farshid: * function sanitizeFormTags * called when ever we need to make <form> tags call rico functions * */ function sanitizeFormTags(){ /* * get all <form> tags and pit them in formtags variable */ formtags = document.getElementsByTagName('form'); /* * run throgh all formtags: */ for(var i = 0; i < formtags.length; i++){ /* * first we will check if the form action is compelete, many forms * hase relative actions to the page they are loaded in. * this needs some work, to do its job properly. * * NOTICE: setAttributeNode is not supported in explorer. * */ if(formtags[i].getAttribute('action').indexOf('http://')!=0){ actionAttribut = document.createAttribute("action"); actionAttribut.nodeValue = '<{$xoops_url}>/'+formtags[i].getAttribute('action'); formtags[i].setAttributeNode(actionAttribut); } /* * * Next we will check for these: * formtags[i].getAttribute('method') != '' form hase some methods! * formtags[i].getAttribute('method') == 'get' in this part we are going to sanitize forms with ger method * formtags[i].getAttribute('action').indexOf('<{$xoops_url}>' action attrin starts with our site url * */ if((formtags[i].getAttribute('method') != '') && (formtags[i].getAttribute('method') == 'get') && (formtags[i].getAttribute('action').indexOf('<{$xoops_url}>') == 0)){ /* * we are in our form with get methis, lets take all form elements */ formElements = formtags[i].elements; /* * loop throgh all elements to find submit and button types. */ for(var j =0; j<formElements.length; j++){ /* * in case we found a submit type, we will change the type to button (we do not want the form to be submited!) * formElements[j].getAttribute('type') == 'submit' type is submit * !formElements[j].getAttribute('onclick') we will sanitize if there is no onClick attribute * formElements[j].getAttribute('onclick').indexOf('submitFormGet')==0 and if it has some onClick it should be the one we have added. * so what! lets do it again, if we are on another page and the forms * array (document.forms) is changed then the button will submit another form. */ if((formElements[j].getAttribute('type') == 'submit') && (!formElements[j].getAttribute('onclick') || (formElements[j].getAttribute('onclick').indexOf('submitFormGet')==0))){ /* * so we should change this submit type, and add the onClick attribute to it. */ typeAttribut = document.createAttribute("type"); typeAttribut.nodeValue = "button"; formElements[j].setAttributeNode(typeAttribut); /* * this button will call submitFormGet(form) * the form is the one we are in now: document.forms[i] */ onClickAttribut = document.createAttribute("onclick"); onClickAttribut.nodeValue = "submitFormGet(document.forms["+i+"]);"; formElements[j].setAttributeNode(onClickAttribut); /* * so what if we find a button that we have alredy sanitized, but as we are in another page the refrence to form * element is wrong! lets fix it now: */ }else if((formElements[j].getAttribute('type') == 'button') && (!formElements[j].getAttribute('onclick') || (formElements[j].getAttribute('onclick').indexOf('submitFormGet')==0))){ onClickAttribut = document.createAttribute("onclick"); onClickAttribut.nodeValue = "submitFormGet(document.forms["+i+"]);"; formElements[j].setAttributeNode(onClickAttribut); } } /* * this part will do the same thing with the post method forms. * this part should be combined with the previous part. */ }else if((formtags[i].getAttribute('method') != '') && (formtags[i].getAttribute('method') == 'post') && (formtags[i].getAttribute('action').indexOf('<{$xoops_url}>') == 0)){ formElements = formtags[i].elements; for(var j =0; j<formElements.length; j++){ if((formElements[j].getAttribute('type') == 'submit')){ typeAttribut = document.createAttribute("type"); typeAttribut.nodeValue = "button"; formElements[j].setAttributeNode(typeAttribut); if(!formElements[j].getAttribute('onclick')){ onClickAttribut = document.createAttribute("onclick"); /* * some forms are posted based on the submitter name so lets pass the submiter name * to the poster function. */ if(document.createAttribute("name")){ onClickAttribut.nodeValue = "submitFormPost(document.forms["+i+"],this.name);"; }else{ onClickAttribut.nodeValue = "submitFormPost(document.forms["+i+"],'');"; } formElements[j].setAttributeNode(onClickAttribut); }else{ alert(formElements[j].getAttribute('onclick')); /* onClickAttribut = document.createAttribute("onclick"); onClickAttribut.nodeValue = "submitFormPost(document.forms["+i+"]);"; formElements[j].setAttributeNode(onClickAttribut); */ } }else if((formElements[j].getAttribute('type') == 'button') && (formElements[j].getAttribute('onclick').indexOf('location=') == 0)){ //alert(formElements[j].getAttribute('onclick')); onClickAttribut = document.createAttribute("onclick"); onClickAttribut.nodeValue = "submitFormPostByLocation(document.forms["+i+"],this);"; formElements[j].setAttributeNode(onClickAttribut); } } } } } /* * * function sanitizeModuleATags(string: module directory name) * just like sanitizeATags function, but for links in a module * called when ever we need to make <a> tags in a module * call rico functions * 1- create and attach proper onClick attribute * 2- remove the href * 3- some criteria should exict as we need some links not vhanged (ex. <{$xoops_url}>/admin.php) * * NOTIC: sanitizeATags function should always be called befor calling this function. * */ function sanitizeModuleATags(moduleDir){ /* * just get tags in the ajax_content part. */ modulearea = document.getElementById('ajax_content'); atags = modulearea.getElementsByTagName('a'); for(var i = 0; i < atags.length; i++){ /* * (atags[i].href != '') we have some href to handle * atags[i].target != '_blank' page is not opening in a new window * atags[i].getAttribute('target') != '_blank' I don't know why I put this here! * atags[i].href.indexOf('<{$xoops_url}>/modules/'+moduleDir) == 0 the link is in the module directory * atags[i].href.indexOf('userinfo.php') != -1 the link is not pointing to user info, if it is so ot os alredy sanitized */ if((atags[i].href != '') && (atags[i].target != '_blank') && (atags[i].getAttribute('target') != '_blank') && ((atags[i].href.indexOf('<{$xoops_url}>/modules/'+moduleDir) == 0) || (atags[i].href.indexOf('userinfo.php') != -1))){ onClickAttribut = document.createAttribute("onClick"); onClickAttribut.nodeValue = "getPage('"+atags[i].href+"');"; atags[i].setAttributeNode(onClickAttribut); //atags[i].setAttribute(onClickAttribut); atags[i].href = "javascript:void(0);"; }else if((atags[i].href.indexOf('<{$xoops_url}>') == 0) && (atags[i].getAttribute('target') != '_blank')){ onClickAttribut = document.createAttribute("onClick"); xoopsUrl = '<{$xoops_url}>'; onClickAttribut.nodeValue = "getPage('<{$xoops_url}>/modules/"+moduleDir+atags[i].href.substring(xoopsUrl.length,atags[i].href.length)+"');"; atags[i].setAttributeNode(onClickAttribut); //atags[i].setAttribute(onClickAttribut); atags[i].href = "javascript:void(0);"; } } } /* * Create a page_object object which is responsible for handling our pages * This part has been modified from rico examples. */ var page_obj = Class.create(); /* * our page hase some attributes: * url: page url * title: page title that will be replaced to show current page title in the browser * module: in the page is a module page: module directory name, else this will be: "_nomodule_" * time: if the page is a redirecting page, the time to wait before redirecting * href: the url we will redirect to after (time) seconds * content: page content */ page_obj.attributes = [ "url", "title", "module", "time", "href", "content" ]; page_obj.prototype = { initialize: function(url) { }, ajaxUpdate: function(ajaxResponse) { this.placePage(ajaxResponse.childNodes); }, placePage: function(page_responce) { /* * page_responce is the xml part we have generated for the page; * it is somthing like this: * * <page url="page url" title="page Title" module="module directory" time="" href=""> * <content> * <![CDATA[not well formed html content here]]> * </content> * <dbug url="localhost%3A81%2Fxoops1016ajax%2F%3F"> * <![CDATA[not well formed html dbug data here]]> * </dbug> * </page> * * page content and debug data will be loaded as CDATA section. * other data (attributes) are automaticaly mapped by Rico. */ var pageHolder = ''; /* * get title, url and module directory. */ pageTitle = page_responce[0].getAttribute('title'); pageUrl = page_responce[0].getAttribute('url'); pageModule = page_responce[0].getAttribute('module'); /* * get redirect time and url, and see if we should do redirect the page! */ redirectTime = page_responce[0].getAttribute('time'); redirectUrl = decodeURIComponent(page_responce[0].getAttribute('href')); shouldRedirect = ((redirectTime != '') && (redirectUrl != '')); /* * get page content and debug data */ pageHolder += page_responce[0].childNodes[0].childNodes[0].nodeValue; debugData = page_responce[0].childNodes[1].childNodes[0].nodeValue; /* * set page title, content and debug data. */ document.title = pageTitle; document.getElementById('ajax_content').innerHTML = pageHolder; document.getElementById('debugWindowDebugArea').innerHTML = 'Debug Data for URL: '+decodeURIComponent(pageUrl)+'n'+debugData; document.getElementById('debugWindowDebugArea').style.visibility = 'visible'; /* * if we are in a module sanitize module tags, else * do normal sanitize. */ if(pageModule != '_nomodule_'){ sanitizeModuleATags(pageModule); }else{ sanitizeATags(); } /* * sanitze forms */ sanitizeFormTags(); /* * inform user that the page is loaded and * give him/her a link to the main url. */ document.getElementById('pageLoadingMessage').innerHTML = 'main page url: <a href="http://'+decodeURIComponent(pageUrl)+'" target="_blank">http://'+decodeURIComponent(pageUrl) + '</a>'; /* * if we should redirect, call the getPage(url) function after time*1000 milsec */ if(shouldRedirect){ window.setTimeout("getPage('"+redirectUrl+"')",redirectTime*1000); } } } var page_obj; /* * this is the same as page object, just for blocks, * right now just left blocks. * */ var block_obj = Class.create(); block_obj.attributes = [ "bid", "title", "module", "content" ]; block_obj.prototype = { initialize: function(url,blockSide) { this.url = url; this.blockSide = blockSide; }, ajaxUpdate: function(ajaxResponse) { this.placeBlock(ajaxResponse.childNodes); }, placeBlock: function(block_responce) { var blockHolder = ''; blocks = block_responce[0].childNodes; elementToAdd = document.getElementById('leftcolumn'); elementToAdd.innerHTML = ''; for(var i=0;i<blocks.length;i++){ addBlockToPage(this.blockSide,blocks[i].attributes['title'].nodeValue,blocks[i].childNodes[0].childNodes[0].nodeValue); } sanitizeATags(); sanitizeFormTags(); document.getElementById('blockLoadingMessage').innerHTML = ''; } } var block_obj; function addBlockToPage(blockSide,blockTitle,blockContent){ switch(blockSide){ case 'Left': blockElement = document.getElementById('leftcolumn'); break; } newBlockTitleDiv = document.createElement('div'); classAttrib = document.createAttribute("class"); classAttrib.nodeValue = "blockTitle"; newBlockTitleDiv.setAttributeNode(classAttrib); newBlockTitleDiv.innerHTML = blockTitle; blockElement.appendChild(newBlockTitleDiv); newBlockContentDiv = document.createElement('div'); classAttrib = document.createAttribute("class"); classAttrib.nodeValue = "blockContent"; newBlockContentDiv.setAttributeNode(classAttrib); newBlockContentDiv.innerHTML = blockContent; blockElement.appendChild(newBlockContentDiv); } function registerAjaxPage(url) { document.getElementById('pageLoadingMessage').innerHTML = 'Loading Page, Use this link if the page failed Loading: <a href="'+url+'" target="_blank">'+url+'</a>'; ajaxEngine.registerRequest( 'getPage', url ); //ajaxEngine.registerAjaxElement( 'ajax_content' ); ajaxEngine.registerAjaxObject( 'page', new page_obj(url) ); } function getPage(url) { registerAjaxPage(url); ajaxEngine.sendRequest( 'getPage', "ajaxpage=1" ); getLeftBlocks(url); } function registerAjaxBlocks(url,blockSide) { document.getElementById('blockLoadingMessage').innerHTML = ' and Loading '+blockSide+' Blocks...'; if(blockSide == 'Left'){ ajaxEngine.registerRequest( 'getLeftBlocks', url ); } ajaxEngine.registerAjaxObject( 'blocks', new block_obj(url,blockSide) ); } function getLeftBlocks(url){ registerAjaxBlocks(url,'Left'); params_arr = Array("ajaxpage=1","leftBlocks=1"); params = params_arr.join('&'); ajaxEngine.sendRequest( 'getLeftBlocks', {parameters:params} ); } function submitFormGet(form){ var formElements = form.elements; var formParams = Array('ajaxpage=1'); for(var j =0; j<formElements.length; j++){ switch(formElements[j].type){ case 'text': case 'hidden': formParams.push(encodeURIComponent(formElements[j].getAttribute('name'))+"="+encodeURIComponent(formElements[j].value)); break; case 'checkbox': if(formElements[j].checked){ formParams.push(formElements[j].getAttribute('name')+"="+encodeURIComponent(formElements[j].value)); } break; case 'select-one': formParams.push(formElements[j].getAttribute('name')+"="+encodeURIComponent(formElements[j].value)); break; }//switch } registerAjaxPage(form.getAttribute('action')); var params = formParams.join('&'); ajaxEngine.sendRequest( 'getPage', {parameters:params} ); } function submitFormPost(form,elementName){ var formElements = form.elements; var formParams = Array('ajaxpage=1'); if(elementName != ''){ formParams.push(elementName+'='+elementName); } elements = ''; for(var j =0; j<formElements.length; j++){ elements += formElements[j].type+'n'; if(formElements[j].getAttribute('name') != null){ switch(formElements[j].type){ case 'text': case 'hidden': case 'select-one': case 'textarea': case 'password': formParams.push(formElements[j].getAttribute('name')+"="+encodeURIComponent(formElements[j].value)); break; case 'checkbox': case 'radio': if(formElements[j].checked){ formParams.push(formElements[j].getAttribute('name')+"="+encodeURIComponent(formElements[j].value)); } break; case 'file': formParams.push(formElements[j].getAttribute('name')+"="+encodeURIComponent(formElements[j].value)); break; }//switch } } registerAjaxPage(form.getAttribute('action')); var params = formParams.join('&'); ajaxEngine.sendRequest( 'getPage', {method:'post',parameters:params} ); } function submitFormPostByLocation(form,element){ //var formElements = form.elements; //var Location = element.value; //var formParams = Array('ajaxpage=1'); alert('called'); //elements = ''; /* for(var j =0; j<formElements.length; j++){ //elements += formElements[j].type+'n'; switch(formElements[j].type){ case 'text': case 'hidden': formParams.push(encodeURIComponent(formElements[j].getAttribute('name'))+"="+encodeURIComponent(formElements[j].value)); break; case 'checkbox': if(formElements[j].checked){ formParams.push(formElements[j].getAttribute('name')+"="+encodeURIComponent(formElements[j].value)); } break; case 'select-one': formParams.push(formElements[j].getAttribute('name')+"="+encodeURIComponent(formElements[j].value)); break; }//switch } */ //formParams.push(encodeURIComponent(element.getAttribute('name'))+"="+encodeURIComponent(formElements[j].value)); //alert(elements); //registerAjaxPage(form.getAttribute('action')); //var params = formParams.join('&'); //alert(params); //ajaxEngine.sendRequest( 'getPage', {method:'post',parameters:params} ); } </script>
The code has some comments that I wish helps you.
I am going to do something new: bringing the admin area to XOOPS front side, just like liferay portal.
and another idea is a full flash theme based on this aproach, I am thinking of this, any ideas? or do you think this is good or bad?
there is some other changes in the theme, I will put the file for download as soon as possible.
and thanks for all your comments;
@highlander
I found the article in French, so I need the English version.