January 31, 2012
No Comments
I was recently asked by a client to create a scrollable, navigation menu for their site. However, they wanted it to have an onHover submenu that expanded to the side, over the top of the scrollbar.
The problem with this is that there is noway to do this using normal css, over the overflow:scroll hides the sub menu. If you put the submenus into a different div outside the scrollable area, then you can run into problems with the onHover thinking you’ve left the target.
To get round this I put together the following jQuery, HTML and CSS, which I hope will help someone.
<div class="categories">
<ul>
<li class="level0 first parent">
<a href="path/to/link">
<p>First Item</p>
</a>
<ul style="display:none">
<li class="level1 first parent">
<a href="path/to/link">
<p>sublevel-1</p>
</a>
<ul style="display:none">
<li class="level2 first">
<a href="path/to/link">
<p>sub-sublevel1</p>
</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="level0">
<a href="path/to/link">
<p>Second Item</p>
</a>
</li>
</ul>
<div id="hoverMenu" style="display: none; ">
<div id="subHoverMenu" style="display: none; "></div>
</div>
</div>
.categories{background:white;height:310px;overflow:scroll;overflow-x:hidden;}
.categories .active{background:red;}
.categories ul{padding:9px 10px 0 10px;}
.categories ul li a{color:black;height:21px;line-height:21px;}
.categories ul li a p{font-size:13px;padding:0 0 0 0;margin:0 0 0 0;white-space:nowrap;}
.categories #hoverMenu{background:white;height:auto;position:absolute;width:auto;z-index:150;}
.categories #hoverMenu .active{background:red;}
.categories #hoverMenu li{padding:5px 10px 5px 20px;}
.categories #hoverMenu p{color:black;font-size:13px;white-space:nowrap;}
.categories #hoverMenu #subHoverMenu{background:white;width:auto;height:auto;position:absolute;z-index:150;}
.categories #hoverMenu #subHoverMenu .active{background:red;}
jQuery(document).ready(function() {
jQuery(".categories li.level0").mouseenter(function() {
jQuery(this).siblings().removeClass('active');
jQuery(this).addClass('active');
if(jQuery(this).hasClass('parent')) {
jQuery('#hoverMenu ul').remove();
var pos = jQuery(this).position();
var mouseX = pos.left + 175;
var mouseY = pos.top;
var subMenu=jQuery(this).children('ul:first')
subMenu.clone(true, true).show().appendTo('#hoverMenu');
jQuery('#hoverMenu').css({'top':mouseY,'left':mouseX});
jQuery('#hoverMenu').show();
} else {
jQuery('#hoverMenu ul').remove();
jQuery('#hoverMenu').hide();
}
})
jQuery(".categories li.level1").bind('mouseenter', function() {
jQuery(this).siblings().removeClass('active');
jQuery(this).addClass('active');
if(jQuery(this).children('ul').length) {
jQuery('#subHoverMenu').empty();
var subPos = jQuery(this).position();
var subMouseX = jQuery(this).outerWidth();
var subMouseY = subPos.top;
var subSubMenu=jQuery(this).children('ul:first')
subSubMenu.clone(true, true).show().appendTo('#subHoverMenu');
jQuery('#subHoverMenu').css({'top':subMouseY,'left':subMouseX});
jQuery('#subHoverMenu').show();
} else {
jQuery('#subHoverMenu').empty().hide();
}
})
jQuery(".categories li.level2").bind('mouseenter', function() {
jQuery(this).siblings().removeClass('active');
jQuery(this).addClass('active');
})
jQuery('#hoverMenu').mouseleave(function(){
jQuery('#hoverMenu ul').remove();
jQuery('#hovermenu').hide();
jQuery('#subHoverMenu').empty().hide();
})
jQuery('#subHoverMenu').mouseleave(function(){
jQuery(this).empty().hide();
})
jQuery('.categories').mouseleave(function() {
jQuery('#hoverMenu ul').remove();
jQuery('#hoverMenu').hide();
jQuery('#subHoverMenu').empty().hide();
jQuery(".col-left .category-list .categories li").removeClass('active');
})
})
Obviously, change styles and content as required
I rely on multiple desktops in order to keep my workflow organised. However each time I start up my computer I have to move these windows onto the correct desktop, which is a pain. Thankfully there is a way to place each window onto it’s own desktop when your computer starts. This will explain the basics of doing this.
First you need to install a tool called wmcrtl. On ubuntu you can do this by running this command
sudo apt-get install wmctrl
Once this is installed you need to see how it thinks you desktop is set up. You can do this by running this command
wmctrl -d
which give me the following result
0 * DG: 13440x1050 VP: 0,0 WA: 0,24 3360x1002 Workspace 1
The important part is the 13440×1050 – which corresponds to 8 1680×1050 desktops. Some versions of ubuntu put each desktop as a separate workspace, if so you’ll need to modify the instructions slightly.
At this point you can move you windows around so they are where you want them to be. Once you are happy with your layout, run the following command
wmctrl -lG
which will give you something similar to this
0x0340002e 0 3360 48 1680 1002 ross-desktop Add New Post ‹ Edmonds Commerce — WordPress - Chromium
0x02a00077 0 23002 106 253 970 ross-desktop Buddy List
0x02200004 0 0 58 1680 1021 ross-desktop Terminal
0x06400003 0 6720 58 1680 1021 ross-desktop *untitled - Geany
...
This can be broken down as follows
window-id desktop-number x-ofset y-ofset width height machine-name window-title
Using this information you can put together a script that will run at startup to launch you windows.
NB This script relies on the window title to move a window. This works because the script will be run at startup and it is assumed that you will only have one instance of each program running. If you plan to have multiple windows open, then you will need to get the window-id, go through the man pages for ways of doing this.
#!/bin/bash
geany /tmp/scratch.sql /tmp/scratch.php &
x-terminal-emulator &
# allow the windows to spawn before moving them
sleep 5
# select and move the windows
# format wmctrl -r "window to move" -e gravity,x-pos,y-pos,width,height (-1 keeps the current value)
wmctrl -r "scratch.php - /tmp - Geany" -e 0,6720,0,-1,-1
wmctrl -r "Terminal" -e 0,3360,0,-1,-1
save the file and make it executable, and then run it at startup to have your windows automatically appear where you want them. This is just scratching the surface of what wmctrl can do, so if you want to carry out more windows management from the command line go through the man pages and see if it can do what you want.
January 30, 2012
No Comments
So you have a plesk backup file and you want to extract and open the files from it? No problem. This blog will show you how.
The file is a mime file. The “mpack” package will let you unpack it.
First we install the “mpack” package
sudo apt-get install mpack
Let’s imagine your file is called “pleskDump.gz”. If it doesn’t have a “.gz” at the end it might not be bad to add it as some environments will complain if it’s absent.
Next we unzip the file
gunzip pleskDump.gz
Now let’s un-mime the file
mkdir pleskDumpOutput
cd pleskDumpOutput
cat ../pleskDump | munpack
Now we have a bunch of regular tar files, but be careful, if we just extract them, the root folders will not be recreated. In order to keep things together, it’s best now to look at the output you have. Let’s take a made up example:
example-domain.com.httpdocs
Note that the format is essentially domain.rootfolder or in another way, the tar files have your domain name they are archiving, then a dot, then the name of the root folder they made up. We take that root folder and create it like this:
mkdir rootfolder
Now let’s apply that idea to our previoud example; “example-domain.com”
mkdir httpdocs
It’s time to untar into the folder you just created, let’s assume you just created “httpdocs”
tar -xvf example-domain.com.httpdocs -C httpdocs
There you go! You can now output any of the folders you wanted.
plesk, By:
admin
No Comments
Tags:
backup,
developer,
development,
extract,
files,
hosting,
linux,
plesk,
server,
solution,
tip
January 23, 2012
No Comments
If you want to serve up text files for download (perhaps product feeds etc) then you might like this little snippet.
Not only will it force the file to be downloaded but it allows you to specify a custom filename that it should be saved as.
if(isset($_GET['download_file'])){
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=Export.txt");
readfile('Export.txt');
die;
}
php, By:
admin
No Comments
Tags:
as,
custom,
download,
export,
feed,
file,
filename,
force,
header,
php,
save,
text,
txt
The first development release of Magento 2 has a few areas worthy of note for developers of the coming changes to Magento.
Magento 2 now requires PHP 5.3
Zend is still version 1.11.1.
Magento 2 now implements templates on a per modules basis. So now all the different bits of the theme are separated into the modules it belongs to. This means that any existing version 1 theme cannot be dropped into version 2.
Themes in Magento 2 have the concept of variations of the same theme. So a theme can have different CSS and images but use the same templates, this can be configured per store per user agent in the admin. This is useful if you have different seasonable themes that are the same as each other but with a few different images and colours. To achieve the same in Magento 1 you would have to use packages and Magento’s ability to cascade up, this is not longer necessary.
This development release of Magento has a major focus on updating the theme and template system to be more ridged unlike Magento version 1 where the template files could be basically any where within a theme.
magento, By:
admin
No Comments
Tags:
2,
5.3,
developer,
magento,
magento 2,
php,
php 5.3,
two,
version,
web developer,
zend
Magento version two is coming. For those of us who are eagerly awaiting the next major version of the most popular and powerful open source e-commerce platform, you can now see, track and download the code on GitHub.
Not had chance to have an in depth look as yet but we expect great things!
https://github.com/magento/magento2
magento, By:
admin
No Comments
Tags:
2,
e-commerce,
git,
github,
hope,
magento,
php,
source,
two,
version
January 21, 2012
5 Comments
If you are thinking of adding a confirmation of e-mail address to the front-end registration pages of your store e.g the Checkout billing page or the customer account registration, the little snippets below could be of use to you
For the Checkout billing page
1. Locate the magento checkout billing page (billing.phtml) which can be found in app/design/frontend/default/
/template/checkout/onepage
2. Add code 1 below where situable;
Code 1
<div class="field">
<label for="billing:confirm_email" class="required"><em>*</em><?php echo $this->__('Confirm Email Address') ?></label>
<div class="input-box">
<input type="text" name="billing[confirm_email]" title="<?php echo $this->__('Confirm Email') ?>" id="billing:confirm_email" class="input-text required-entry validate-cemail" />
</div>
For the validation of this email confirmation field with the actual email field
3. Locate the Javascript file which Magento uses for validation (validation.js) in /js/prototype
4. Add code 3 where suitable e.g immediately after this line(code 2) in validation.js
Code 2
return !(pass.length < 7);
}],
Code 3
['validate-cemail', 'Please make sure your emails match.', function(v) {
var conf = $$('.validate-cemail')[0];
var pass = false;
if ($('email')) {
pass = $('email');
}
var emailElements = $$('.validate-email');
for (var i = 0; i < emailElements.size(); i++) {
var emailElement = emailElements[i];
if (emailElement.up('form').id == conf.up('form').id) {
pass = emailElement;
}
}
if ($$('.validate-admin-email').size()) {
pass = $$('.validate-admin-email')[0];
}
return (pass.value == conf.value);
}],
Then that should just do exactly what you want.
For the Customer Account Registration page
1. Locate the magento account register page ,register.phtml in
app/design/frontend/
/default/template/persistent/customer/form/
2. Include code 4 where suitable
Code 4
<div class="field">
<label for="confirm_email" class="required"><em>*</em><?php echo $this->__('Confirm Email Address') ?></label>
<div class="input-box">
<input type="text" name="confirm_email" title="<?php echo $this->__('Confirm Email') ?>" id="confirm_email" class="input-text required-entry validate-cemail" />
</div>
</div>
After this, you should have another field on your registration page which can be subjected to any styling you need to do, most importantly when styling do not change the tag id’s and class names, in a situation where you need to change them, you must also change the javascript selectors accordingly.
I hope this works for you.
January 20, 2012
No Comments
If you have created a new product type and need to enable it to be included with configurable products you need to let Magento know that it should allow your product type to work with configurable products. To do this open your config xml and add the following xml.
<config>
<global>
<catalog>
<product>
<type>
<configurable translate="label" module="catalog">
<allow_product_types>
<custom_type_name/>
</allow_product_types>
</configurable>
</type>
</product>
</catalog>
</global>
</config>
This tells Magento to include your product type for use with configurable products.
I recently needed magento to be able to load a product, and if that product was part of a configurable product detect this and return the parent product if that existed. Looking around google I came across this code snippet and thought it should work
$_product = Mage::getModel('catalog/product')->load($productId);
$parentIdArray = $_product->loadParentProductIds()
->getData('parent_product_ids');
if(!empty($parentIdArray)) {
// do something
}
The problem is that the loadParentProductIds method was depreciated in 1.4.2.0 and I’m running 1.6. The new way of doing detecting if a product has a parent is to do this
$configurable_product_model = Mage::getModel('catalog/product_type_configurable');
$parentIdArray= $configurable_product_model->getParentIdsByChild($productId);
if(!empty($parentIdArray)) {
// do something
}
Using this method I overrode the Mage_Catalog_Model_Product class and added this method, which will always return a configurable product if the product is associated with one. Be aware, that if you products belong to more than one configurable product you will have to modify the logic
public function getConfigurableProduct() {
switch ($this->type_id) {
case 'configurable':
return $this;
break;
default:
$configurable_product_model = Mage::getModel('catalog/product_type_configurable');
$parentId= $configurable_product_model->getParentIdsByChild($this->getId());
if(isset($parentId[0])) {
$this->load($parentId[0]);
}
break;
}
return $this;
}
January 19, 2012
No Comments
If you are a PHP developer looking for a job in the Bradford area then please do get in touch with Edmonds Commerce.
We are a team of PHP developers who focus on e-commerce based on open source packages such as Magento, osCommerce, Prestashop, OpenCart and others. We also do a fair bit of WordPress, Drupal, Zend Framework etc as well. We even do bespoke PHP development.
If you are a skilled PHP developer and would like to join a team of enthusiastic developers in a friendly flexible environment with a focus on productivity, personal skills development and fun then get in touch with us today.