Posts from August 2011.

Replace Spotlight With Alfred App

fetchit-21

If you own a Mac and you haven’t heard of Alfred App then you’ve likely been living in a bunker for a while.

At very least Alfred allows you to quickly start applications. If you choose to delve deeper you can use it to search and open files, run applescripts, quick jump to webpage searches, send emails, control iTunes and 999 other clever tricks.

When you first get your Mac you will likely have heard of Spotlight, a built in application that can be used to search applications and files. It’s hotkey is cmd-space. It isn’t as flexible as Alfred App but it has the best hotkey combination going.

Before we start if you’ve turned off Alfred’s menu bar icon, turn it back on in Alfred appearance preferences. It’s makes for the easiest method of opening during hotkey move.

Here is how to move Alfred App to use cmd-space and Spotlight to use ctrl-space:

System Preferences -> Keyboard -> Keyboard Shortcuts

spotlight keyboard shortcuts

1) In the left column click Spotlight.
2) In the right column click the current key combination for spotlight of ⌘Space (cmd-space) and input your replacement key combination. I recommend ^Space (ctrl-space) although some other applications occasionally reserve it (such as Things App). At this point if you can see it you could also switch the second hotkey combination over to ⌥^Space (alt-ctrl-space).
3) Don’t worry about remembering the old hotkeys. If you change your mind later as you can click Restore Defaults to undo your changes.

You can close system preferences now.

So we’ve moved Spotlight, but now we need to move Alfred to ⌘Space (cmd-space).

Click on Alfred’s top hat menu bar icon and select preferences. (you may need to restart Alfred at this point for it to recognise that you’ve moved Spotlight to a new hotkey.

Choose General and you should see a large box Alfred Hotkey box. Click it and press our new hotkey for Alfred App.
⌘Space (cmd-space)

Alfred Preferences

And that’s it. You should now see Spotlight when you hit ^Space (ctrl-space) and Alfred when you click ⌘Space (cmd-space).

Yii (and Yii2) UpdateAll Example

wp-carousel-20

This is a simple example of how to use Yii’s updateAll():

In this example we want to set status = 1 WHERE type_id = 1 AND status = 0

Note this is a simple example where we are only updating one column and using a string for our condition. There are more complex options available.

Comment::model()->updateAll(array( 'status' => 1 ), 'type_id = 1 AND status = 0' );

So as you can see first comes an array of column => new_value pairs, then a condition string which is pretty much used as the WHERE clause.

An example of updating more than one column:

Comment::model()->updateAll(array( 'status' => 1, 'updated' => '2011-08-25 09:33:23' ), 'type_id = 1 AND status = 0 ' );

Update. Yii2 example:

Updating a single column:

Comment::updateAll(['status' => 1], 'type_id = 1 AND status = 0');

Updating multiple columns:

Comment::updateAll(['status' => 1, 'updated' => '2011-08-25 09:33:23'], 'type_id = 1 AND status = 0' );

Hide Google Related Bar On Your Website With CSS

fetchit-21

Update: The css method of removing / hiding the related bar no longer works. See the new (javascript only) fix at bottom of this post.

Google recently released a new browser extension for Internet Explorer and Google Chrome called Google Related. I’m sure it will be coming to Firefox soon.

The extension adds a bar to the bottom of some website which shows things like maps, video, images, reviews and related websites.

To get the bar to show at the bottom of your browser Google injects an iframe at the end of your body tag which is positioned with css to always sit at the bottom of your browser and has a high z-index to ensure it always sits above everything else on the page.

No longer working css fix

The beauty of Google Related using an iframe in your own pages html is that you can hide it using a single css declaration. For now it’s as simple as…

iframe.grelated-iframe {
	display: none;
}

…although in the future, if Google get wise to webmasters hiding their Google Related bar you may need to do something like

iframe.grelated-iframe {
	left:-99999px !important;
	display: none !important;
}

Update November 2011

<iframe frameborder="0" src="http://www.gstatic.com/webgps/grelated_0_6_9/html/grelated_bar_iframe.html" style="border-top-width: 0px !important; border-right-width: 0px !important; border-bottom-width: 0px !important; border-left-width: 0px !important; border-style: initial !important; border-color: initial !important; bottom: 0px !important; display: block !important; left: 0px !important; margin-top: 0px !important; margin-right: 0px !important; margin-bottom: 0px !important; margin-left: 0px !important; outline-width: 0px !important; outline-style: initial !important; outline-color: initial !important; padding-top: 0px !important; padding-right: 0px !important; padding-bottom: 0px !important; padding-left: 0px !important; position: fixed !important; right: 0px !important; top: auto !important; vertical-align: baseline !important; visibility: visible !important; width: 100% !important; z-index: 2147483647 !important; height: 49px !important; " scrolling="no"></iframe>

As you can see Google no longer makes it easy to hide the tool using css. They’ve ensured every css property you could use to hide the iframe is forced as !important.

The only option left (if you still want to hide the bar) is to use javascript to hide or remove the element.

I’m suggesting a setInterval incase Google does an update which keeps trying to reshow / add the iframe.
I’m suggesting ‘none !important’ because it’s the highest selector value you can add and least likely to be replaced by other css on the page or that Google choose to inject.

setInterval(function()
{
 var ifr = document.body.getElementsByTagName('iframe'), l = ifr.length;
    for(var a = 0; a < l; a++)
    {
        if(ifr[a].src.match(/^http:\/\/www\.gstatic/))
        {
            ifr[a].style.display = 'none !important'
        }
    }
},1000);

That javascript will check all iframes in the page once every second to see if it’s the pesky Google related bar by checking the url (which may need updating in the future!) and hides it if it does.

If you’re unsure of what to do with the javascript code, copy the JavaScript above and paste it into a .js file which is included on every page of your site, or copy the whole next code chunk and paste it just before the closing body tag of your page.

<script type="text/javascript">
setInterval(function()
{
 var ifr = document.body.getElementsByTagName('iframe'), l = ifr.length;
    for(var a = 0; a < l; a++)
    {
        if(ifr[a].src.match(/^http:\/\/www\.gstatic/))
        {
            ifr[a].style.display = 'none !important'
        }
    }
},1000);
</script>

If you use jQuery on your site then the following will do something very similar:

 
setInterval(function()
{
    $('body > iframe[src^=http://www.gstatic]').css({display:'none !important'});
},1000);

Kiwi App Theme Retweeter Text Position Hack

fetchit-21

Kiwi is a twitter client for Mac that offers all the benefits of the Twitter for Mac and more. Check it out.

Anyway, one of kiwi’s most amazing features is templates. You can change standard css, html and images to make the client look exactly how you like. Change the design of the timeline or use one of the free kiwi themes that other people have created.

I was immediately drawn to the Twitlike theme which mimics the existing Twitter for Mac design. After installing it to kiwi there were a couple of things I wanted to change. The first being, if the tweet was actually a retweet, Kiwi inserts the retweet information before the actual tweet text, and I didn’t want it to show above the text, I wanted the retweet information to show below out of the way.

Luckily using a bit of css magic I worked out how to move the retweet information. First I added a border to all <div> tags so I could see what made up the html of the tweets text. Bingo; the retweet information is in it’s own div.

Here is part of my html template:

	<div class="text">
		<div class="recipient">
			%recipient%
		</div>
		<div class="tweet-text">
			%text%
		</div>
	</div>

So the css selector I needed to grab all text was .tweet .text and the selector for the retweet information was .tweet .text div

 
/* the retweet info */
.tweet .tweet-text div {
	overflow: hidden;
	height: 13px;
	position: absolute;
	left: 0;
	bottom: -20px;
}
 
/* the tweet text */
.tweet .text {
    -webkit-user-select: text;
	margin-top: 3px;
	margin-bottom: 5px;
	position: relative;
}
 
/* the tweet text if this is a retweet */
.tweet.retweet .text {
	margin-bottom: 20px;
}

As you can see above. If it’s a retweet I add a larger margin bottom to the text so there is space to show the retweeter information. I then position absolute the retweeter information, give it a fixed height and overflow hidden incase it’s massive.

Kiwi are kind enough to add a .retweet class where applicable, so I can only apply these styles where required. Bingo:

kiki app screen shot

I noticed that someone else asked this question on the kiwi discussion forums and the official kiwi reply was that it was a know request to have a separate template elements for the retweet information. Let’s hope that a new version on Kiwi brings that to us.

css transform rotation and parent element dimensions

fetchit-21

When you use css3 to rotate an element with it’s new transform property, you may find yourself fighting to keep it inside it’s parent.

To clarify, usually rotating an element will first put it into it’s usual position and then literally rotate it around it’s own centre, not caring if it now overlaps elements around it (well I suppose that’s the point sometimes?!?)

I’m using css transform to rotate, in combination with a little javascript to allow images to be rotated (and then saved) as part of PagePlay‘s super simple user interface.

So I initially start out with something like…

--div-------------------------
| ccw                     cw |
| --img--------------------- |
| |                        | |
| |                        | |
| |                        | |
| -------------------------- |
-----------------------------

When you click ccw (counter clockwise) or cw (clockwise) js switched classes on the img and it rotates. Initially, that would give me something like….


       ----------------
       |              |
--div-------------------------
| ccw  |              |   cw |
|      |              i      |
|      |              m      |
|      |              g      |
|      |              |      |
|      |              |      |
-----------------------------
       |              |
       ----------------

(loving the crude graphics? Thought so)

So what I wanted was for the parent div to sit around the image. The problem here is that the div parent doesn’t (and shouldn’t) care about the rotation of it’s child, so we need to make the div larger when it’s rotated. To do this I used a little bit of jQuery and maths to calculate the required additional space…

I don’t know whether the image is going to be taller or wider first, so we need to check that first and come up with a pixel margin to use later…

var img = $('rotator');
var img_w = img.width();
var img_h = img.height();
var the_margin = (img_w > img_h ? (img_w-img_h)/2 : 0);

The img width minus image height divided by 2 is the amount space above and below the standard space the image takes up that it will also need when rotated. If the image is taller than it is wide, we will already have enough space (you could do better by making the div smaller on rotation in this case).

So when we rotate we look at whether the image is rotated or not (rev tells me that here) and then based on that we add or remove the margin we calculated above to the top and bottom of the image to push it’s parent div away from it and make it large enough to accommodate the image.

img.css({marginTop:(rev ? 0 : marg),marginBottom:(rev ? 0 : marg)});

You could certainly do better with dealing with image which are portrait, but then maybe I’ll come back to that another time.