A client wants to move a website they made using Adobe Catalyst to a different hosting provider. I was able to copy the entire website via FTP and move it to the new host. Everything looks fine except for many of the links leaving code that looks like this:
{module_contentholder, name="_U309"} {module_contentholder, name="_U299"}
Does anyone know what this is or how to fix it?
Those are references to Content Holders. They work similarly to PHP's include statement, but the file they reference is fixed to a single path: /_System/ContentHolders/.
You will likely come across more tags like that, such as {module_menu} and {tag_pagecontent}. You'll need to manually adapt them to the whatever the new host uses. The documentation will help: http://docs.businesscatalyst.com/reference/
The obtuse names of the content holders shown in your example indicates the site was likely to have been generated by Adobe Muse, a WYSIWYG editor. I strongly recommend that you find the original .muse project files, and use those to update the site. Muse can compile the site for platforms other than Business Catalyst.
Through research I found out there is no way to get those codes to display properly without editing each page individually. Fortunately, I wrote a PHP script that goes through the code of each page and replaces it automatically.
Step 1: Make a file in the index directory called replacement.php
Step 2: Put this code in
$file = $_GET['file'];
$path = '/path/to/public_html/' . $file;
$file_contents = file_get_contents($path);
preg_match_all("/{module(.*?)}/", $file_contents, $matches);
foreach($matches[0] as $match) {
if(preg_match('/\"([^\"]*?)\"/', $match, $query)) {
$queryNew = str_replace("\"", "", $query[0]);
$queryPath = '/path/to/public_html/_System/ContentHolders/' . strtolower($queryNew) . '.html';
$queryContents = file_get_contents($queryPath);
$file_contents = str_replace($match, $queryContents, $file_contents);
}
}
file_put_contents($path, $file_contents);
Step 3: Replace where it says /path/to/public_html/ to your domain files location.
Step 4: go to http://www.yourdomain.com/replacement.php?file=index.html to change over the index file. You can change "index.html" in the url to any other page you want converted.
Hopefully this helps someone else in the future.
Related
I have baked a File model and controller with default actions. Now I am trying to add an display function which can be used to show images in controlled manner.
I want to protect images so that display function can check does the user have an permissions to view image (image directory is not in a webroot).
I haven't been able to make it work, but when I started from the scratch I managed to find out that really minimal function did work.
Working function looks like this:
public function display($id) {
$this->response->file(ROOT.DS.'img'.DS.'noimage.jpg');
return $this->response;
}
When I add example:
$test=$this->File->findById($id);
to the starting of the function everything breaks.
--> http://www.example.com/files/display/1
The requested file /var/www/example.com/www/img/image.jpg was not found or not readable
Error: The requested address '/files/display/1' was not found on this server.
I have tried with debug zero, file can be found and is readable, obviously because the function without findById works.
Any ideas?
cakephp 2.4.3
You path is totally wrong.
Did you debug() what ROOT.DS.'img'.DS.'noimage.jpg' actually holds?
I bet all the money of the world that you would probably find the solution yourself if you did
The img folder is most likely in webroot
WWW_ROOT . 'img' . DS . 'noimage.jpg'
Note that paths usually end with a DS so no need to add it again.
So if it really is an image folder in ROOT:
ROOT . 'img' . DS . 'noimage.jpg'
Also note that you can easily check if a path is valid using
file_exists()
If the file has the correct file permissions this should return true.
EDIT:
$this->File->...: File is not a good choice for a model name as it collides with the existing core class in Utility. You need to be a little bit more creative with your model naming scheme.
I'm currently setting up a Magento shop that will support a few different languages.
One issue that I ran into is that I can't find out how to link two CMS pages together, so that when a user switches their language, they are automatically forwarded to the current CMS page but in their preferred language. One option would be to use the same URL key for both pages, but that wouldn't be very user friendly as some users would then see URL keys not in their native language.
Let me give you an example:
I have an "About us" page. In the English version of the store, the URL of that page is /about-us. Now a German user lands on that page and switches his language. But because the German equivalent to "About us" is "Über uns", the German version of that page is at /ueber-uns, so the user would be presented a 404 page because no German version of /about-us exists.
Does anybody know how to solve this issue?
Update: Did some more research and found nothing. I can't believe I am the only one with this problem? The go-to solution, using the same URL key for all languages, seems very ugly and not very user friendly!
So, the only solution that I found was to manually create a redirect for each page in the Magento Rewrite Rules. Do do that, go to Catalog -> URL Rewrite Management and add each page in the following format:
So if a user is using the Francais store view and requests /url-in-english, the redirect will kick in and redirect the user to /url-in-french.
This is of course not an ideal solution, it would be preferred if two pages could be "linked" directly, but I suppose I will have to use this for the moment. If anybody comes up with a better solution feel free to add yours!
I have seen this bug in Magento CE 1.8.0.0. The problem here was a wrong assignment in \app\code\core\Mage\Core\Model\Url\Rewrite\Request.php.
To solve this problem it is sufficient to change the assignment of $fromStore in the protected function _rewriteDb() within the Mage_Core_Model_Url_Rewrite_Request class from
$fromStore = $this->_request->getQuery('___from_store');
to
$fromStore = Mage::getModel('core/store')->load($this->_request->getQuery('___from_store'), 'code')->getId();
with the result that we can access the $stores array with the right key (with the store id instead of the store code). With this the if statement
if (!empty($stores[$fromStore])) {
works in the right way.
As a reminder: Do not modify core files. Just copy \app\code\core\Mage\Core\Model\Url\Rewrite\Request.php to \app\code\local\Mage\Core\Model\Url\Rewrite\Request.php before any change.
You will find this answer in German here: Rewrite von Seiten in verschiedenen Sprachen und verschiedenen URL Keys in Magento
Above solution works but takes a while. We just did the following to rewrite the language changer url when on a cms page to go to the base url:
Add the following code to app/design/frontend/default/template_name/template/page/switch/languages.html after the part where the $url variable is filled (on our it was like
$url = /*explode( '?',*/$_lang->getCurrentUrl()/*);*/;
so we added the following:
if(($this->getRequest()->getModuleName() == 'cms') && strpos($url,'.com/')){$url = strstr($url, '.com/', true) . '.com/';}
elseif(($this->getRequest()->getModuleName() == 'cms') && strpos($url,'.de/')){$url = strstr($url, '.de/', true) . '.de/';}
elseif(($this->getRequest()->getModuleName() == 'cms') && strpos($url,'.nl/')){$url = strstr($url, '.nl/', true) . '.nl/';}
What I did here is check if on a cms page and check if the url contains either .com/ ; .de/ or .nl and strip the part before then add the domain extension back.
in our example: http://www.mega-watch.com/about-us?blabla will become http://www.mega-watch.com/
Hope this helps someone out..
Anyway to examine the final XML structure magento comes up with after parsing & combining all the different XML files?
There is nothing of that sort which turned up on searching on the internet and I think for someone like me, magento layouts were a bit too much in the beginning & I would try to do everything on the code side.
Another thing which will help in picking up the name of different nodes that we can use, right away from the final XML structure.
Never ran into this but I believe we will have a better picture of what's overriding what.
The following will get you the merged configuration from app/etc/*.xml, app/etc/modules/*.xml, as well as each (active) module's config.xml file; when retrieving the config though there is no indication of what was overwritten, as the merges happen as each config file is being parsed:
Mage::getConfig()->getNode()->asNiceXml(); // or asXML() | asArray() | etc.
However, you seem to be asking about how the application makes use of this information. This is a function of application design.
Also, you mention "all of the different XML files." It's worth noting that these are not maintained in one massive object instance. For example, layout XML is accessed using the layout update object Mage_Core_Model_Layout_Update and can be accessed meaningfully after it's been loaded and manipulated for a given rendering scope (e.g. loadLayout() in a controller action):
Mage::app()->getLayout()->getUpdate()->asString(); // or asSimplexml() or asArray()
Yes - Commercebug. As well as a whole load of other useful features, you can also view the entire XML structure that Magento has produced.
http://store.pulsestorm.net/products/commerce-bug-2
I believe the following will output the XML: echo Mage::getConfig()->getXmlString();
You can create a script with something like this:
header("Content-Type:text/xml");
require_once '../app/Mage.php';
Mage::app();
echo Mage::getConfig()->getXmlString();
based on answer from benmarks I did
echo "<pre>".htmlspecialchars(Mage::getConfig()->getNode()->asNiceXml())."</pre>";
If you want for example to see the blocks configuration in Magento 1 you can put this in a file, place the file at the root of the site and navigate to it in a browser:
<?php
include("app/Mage.php");
Mage::app();
//just see blocks...
echo "<pre>".htmlspecialchars(Mage::getConfig()->getNode()->global->blocks->asNiceXml())."</pre>";
die();
I'm integrating CKEditor into a CakePHP app which is running on a Zeus server (and therefore can't use .htaccess - I have to use rewrite.script instead). Problem is, the paths that CKEditor puts into the head section of the page don't work, so the editor won't load.
For instance, one generated path is:
http://www.example.com/js/ckeditor/config.js?t=B8DJ5M3
If I go to
http://www.example.com/js/ckeditor/config.js
I can see the file, but as soon as I add the ?t=B8DJ5M3 on the end, Cake complains that it can't find the jsController.
I'm not sure what to do about this - whether to dig around in CakePHP, CKEditor or the rewrite.script files! What should I try next?
That query string on the end of your URL is used to make sure the file isn't cached. Seems like something in your GET request configuration/routing on the Zeus server is trying to locate that exact file including the query string. You're going to need to create a Rewrite that performs a goto on the URL minus the query string. I found a pretty solid article in the Drupal forums where someone put together a script that may help you: http://drupal.org/node/46508
RULE_0_START:
# get the document root
map path into SCRATCH:DOCROOT from /
# initialize our variables
set SCRATCH:ORIG_URL = %{URL}
set SCRATCH:REQUEST_URI = %{URL}
# see if theres any queries in our URL
match URL into $ with ^(.*)\?(.*)$
if matched then
set SCRATCH:REQUEST_URI = $1
set SCRATCH:QUERY_STRING = $2
endif
RULE_0_END:
And from there, handle your goto minus the query string. Hope that helps
You can do this
In the view where you want to display the editor, put the following script on the top of the page (or somewhere before textarea which you want to contain editor):
<?php echo $this->Html->script('ckeditor/ckeditor');?>
This scipt will include the "webroot/js/ckeditor.js" file to your view.
Create the textarea and give it a class named "ckeditor"
<?php echo $this->Form->textarea('content',array('class'=>'ckeditor'))?>
Voila! The editor is now displaying instead of raw textarea.
i'm building a iphone app with jqtouch and i use a cachemanifest to cache all the static files (images, css, javascript) to make it load faster. However the page uses php for the dynamic content and i don't want to cache that. So i'm generating the cachemanifest with this php-script(manifest.php):
<?php
header('Content-Type: text/cache-manifest');
echo "CACHE MANIFEST\n";
$hashes = "";
$lastFileWasDynamic = FALSE;
$dir = new RecursiveDirectoryIterator(".");
foreach(new RecursiveIteratorIterator($dir) as $file) {
if ($file->IsFile() && $file != "./manifest.php" &&
substr($file->getFilename(), 0, 1) != ".") {
if(preg_match('/.php$/', $file)) {
if(!$lastFileWasDynamic) {
echo "\n\nNETWORK:\n";
}
$lastFileWasDynamic = TRUE;
} else {
if($lastFileWasDynamic) {
echo "\n\nCACHE:\n";
$lastFileWasDynamic = FALSE;
}
}
echo $file . "\n";
$hashes .= md5_file($file);
}
}
echo "\nNETWORK:\nhttp://chart.apis.google.com/\n\n# Hash: " . md5($hashes) . "\n";
?>
This actually works really good except for one irritating thing:
From what i read somewhere the file that calls the cachemanifest is automaticly included in the manifest and is beeing cached. Wich means that my start-page index.php, where i call the cachemanifest is beeing cached. This leads to very irritating problems.
is there any way to deal with this or any smart workaround? The page is in the cachemanifest listed as NETWORK, but it looks like this is beeing overruled by the fact that the cachemanifest is called from the file.
futta's idea is right, but what you will probably find is that only one section of your frontpage changes often. Leave that empty, then let the rest of the page be cached and don't worry about it. When you visit the page, the cached version is called up instantly, and you can run a script to grab the dynamic page fragment from the server and set it with innerHTML to complete the page. The effect is that there is still one HTTP request (plus one for the manifest), so it is no slower, and it addition you can show part of your app while the dynamic section is being downloaded. If you ever want to refresh the whole page, have a comment in the manifest marking the version, and increment that to reload the whole app.
Clean and neat. I think that is how the system is intended to be used, without trying to avoid a bit of javascript, since that is after all the only way you can play around with the offline and do useful things with the app when offline.
I have the same experience, but have the following possible workaround on my todo-list:
create a manifest with all static assets
include a reference to that manifest in only one html-page (buildCache.php)
check if window.applicationCache is supported and if so:
redirect once per session to cache.html to create/check/update the cache
have buildCache.php display some info about what is being done (using the applicationCache eventlisteners)
have buildCache.php redirect back to normal index (where the manifest is not defined)
I hope (and someone claimed this is the case in a comment on my blog) that all pages on the same domain will use the static assets in the applicationCache, even if the manifest is not referenced in all of them.
Another solution would be to keep your index.php as a blank loading page or splash screen of some sort, then redirecting the user to the actual dynamic php page. Since the manifest is in index.php and index.php redirects to real-index.php the problem might be less anoying.