
WordPress MU and the mysterious disappearing code
As I was in the middle of developing a WordPress MU site for a client of mine, I ran into a very peculiar problem. After importing their blog posts from their old site, I realized there were a few blog posts with embedded Youtube videos that no longer showed the videos. I checked and check again but could not figure out what happened to the embed code. I then decided it was a fluke, found the videos on Youtube again and copy / pasted. When I pushed “Update” the code disappeared. Totally baffled, I thought maybe I did not install WPMU properly. On my initial install I ran into another strange problem with the WYSIWYG visual editor and a reinstall fixed that. So, I spent another 30 minutes reinstalling WPMU.
No luck.
Now frustrated, I started Googling. I came across several forum posts, one of which lead me to a solution. Several people commented on this Embed code disappears (for some users) in Wordpress 2.7 string, having the same, or very similar issue as me. After reading that and several other confirming posts, I found out that WPMU does not allow any additional tags such as <embed>, <iframe>, <form>, etc. WPMU automatically strips posts of these and rightfully so. When you have a large site with multiple users there can be added security issues, especially if a site will allow anyone to sign up. WPMU strips the code as a security measure.
Okay, now for the solution. Because my client will only have very trustworthy administrators, I am utilizing the Unfiltered MU plugin to allow the additional code.
Hopefully I just saved some people a few hours by posting this! Good luck.
Adding a Scrollbar to a Dynamicly Populated Menu List in ActionScript 2.0
Hello people. Yesterday I made a break through. I had been struggling for a few days, attempting to think through how on earth I was going to add a custom scrollbar to TWO dynamically populated menu lists. Well, I solved it. First I found the code I needed and a sample file on kirupa.com (they rock btw).
Before the scrolling, I had an XML document with categories and projects. My code loaded the XML, parsed it and duplicated my menu item (nav button) using the duplicateMovieClip() method. I had it nested in a for loop and so it did all of the naming and depth placement at once. When you clicked on a menu item, a second function was called to populate the second list, passing through the category number and using the same duplicateMovieClip() method.
After looking at the way kirupa.com set up the scrollbar file I realized I needed to put both of my menu lists into container movie clips. That way I would be able to get the _y and _height properties of the grouped nav buttons. I’ve been working a lot with AS 3.0 and needed a refresher in AS 2 on how to nest duplicated items inside a movie clip. I Googled and found this article on actionscript.org reminding me you must use the attachMovie() method.
First I put both nav buttons into their own movie clips and call them: listOneHolder and listTwoHolder. Then I changed both duplicateMovieClip() methods to attachMovie(). Now the code looked like this:
function loadXML(loaded)
{
if (loaded)
{
xml = this.firstChild;
totalSections = xml.childNodes.length;
for (i = 0; i < totalSections; i++)
{
//duplicateMovieClip(myNav, ‘myNav’+i, i + 10); //OLD duplicate nav buttons
_root.listOneHolder.attachMovie(‘myNav’, ‘myNav’ + i, i + 10); //new attach moviessetProperty(_root.listOneHolder['myNav'+i], _x, navX); //set the x property
setProperty(_root.listOneHolder['myNav'+i], _y, navY); //set the y property_root.listOneHolder['myNav'+i].navTxt.htmlText = xml.childNodes[i].attributes.name; // set the text value
}
}
}
note: in addition to having my two menu item movie clips on the stage (myNav and btn), i made sure to right click on them in the library, select “Linkage…” and clicked “Export for ActionScript”.
after that i was able to start tackling the actual scrollbar issue. i figured out that i could use the code from kirupa.com (as seen below) and modify it to accommodate for my two lists.
// KIRUPA //
function scrolling () {
var scrollHeight:Number = theScrollbar.scrollTrack._height;
var contentHeight:Number = contentMain._height;
var scrollFaceHeight:Number = theScrollbar.scrollFace._height;
var maskHeight:Number = maskedView._height;
var initPosition:Number = theScrollbar.scrollFace._y=theScrollbar.scrollTrack._y;
var initContentPos:Number = contentMain._y;
var finalContentPos:Number = maskHeight-contentHeight+initContentPos;
var left:Number = theScrollbar.scrollTrack._x;
var top:Number = theScrollbar.scrollTrack._y;
var right:Number = theScrollbar.scrollTrack._x;
var bottom:Number = theScrollbar.scrollTrack._height-scrollFaceHeight+theScrollbar.scrollTrack._y;
var dy:Number = 0;
var speed:Number = 10;
var moveVal:Number = (contentHeight-maskHeight)/(scrollHeight-scrollFaceHeight);
theScrollbar.scrollFace.onPress = function() {
var currPos:Number = this._y;
startDrag(this, false, left, top, right, bottom);
this.onMouseMove = function() {
dy = Math.abs(initPosition-this._y);
contentMain._y = Math.round(dy*-1*moveVal+initContentPos);
};
};
theScrollbar.scrollFace.onMouseUp = function() {
stopDrag();
delete this.onMouseMove;
};
theScrollbar.btnUp.onPress = function() {
this.onEnterFrame = function() {
if (contentMain._y+speed
if (theScrollbar.scrollFace._y<=top) {
theScrollbar.scrollFace._y = top;
} else {
theScrollbar.scrollFace._y -= speed/moveVal;
}
contentMain._y += speed;
} else {
theScrollbar.scrollFace._y = top;
contentMain._y = maskedView._y;
delete this.onEnterFrame;
}
};
};
theScrollbar.btnUp.onDragOut = function() {
delete this.onEnterFrame;
};
theScrollbar.btnUp.onRelease = function() {
delete this.onEnterFrame;
};
theScrollbar.btnDown.onPress = function() {
this.onEnterFrame = function() {
if (contentMain._y-speed>finalContentPos) {
if (theScrollbar.scrollFace._y>=bottom) {
theScrollbar.scrollFace._y = bottom;
} else {
theScrollbar.scrollFace._y += speed/moveVal;
}
contentMain._y -= speed;
} else {
theScrollbar.scrollFace._y = bottom;
contentMain._y = finalContentPos;
delete this.onEnterFrame;
}
};
};
theScrollbar.btnDown.onRelease = function() {
delete this.onEnterFrame;
};
theScrollbar.btnDown.onDragOut = function() {
delete this.onEnterFrame;
};
if (contentHeight
theScrollbar.scrollFace._visible = false;
theScrollbar.btnUp.enabled = false;
theScrollbar.btnDown.enabled = false;
} else {
theScrollbar.scrollFace._visible = true;
theScrollbar.btnUp.enabled = true;
theScrollbar.btnDown.enabled = true;
}
};
In order to accommodate for my two lists I needed to modify the function to have a few parameters passed through … those were the scrollbar instance (i put two on my stage, one for each list), the mask instance (again, two on each stage, one for each list), and the list. So my new function looked like this:
function goScrolling (_mc, mask_mc, listHolder_mc)
{
var scrollHeight:Number = _mc.scrollTrack._height;
var contentHeight:Number = listHolder_mc._height;
var scrollFaceHeight:Number = _mc.scrollFace._height;
var maskHeight:Number = mask_mc._height;
var initPosition:Number = _mc.scrollFace._y = _mc.scrollTrack._y;
var initContentPos:Number = listHolder_mc._y;
var finalContentPos:Number = maskHeight – contentHeight + initContentPos;
var left:Number = _mc.scrollTrack._x;
var top:Number = _mc.scrollTrack._y;
var right:Number = _mc.scrollTrack._x;
var bottom:Number = _mc.scrollTrack._height – scrollFaceHeight + _mc.scrollTrack._y;
var dy:Number = 0;
var speed:Number = 10;
var moveVal:Number = (contentHeight – maskHeight) / (scrollHeight-scrollFaceHeight);
_mc.scrollFace.onPress = function()
{
var currPos:Number = this._y;
startDrag(this, false, left, top, right, bottom);
this.onMouseMove = function()
{
dy = Math.abs(initPosition – this._y);
listHolder_mc._y = Math.round(((dy * -1) * moveVal) + initContentPos);
}
}
_mc.scrollFace.onMouseUp = function()
{
stopDrag();
delete this.onMouseMove;
}
_mc.btnUp.onPress = function()
{
this.onEnterFrame = function()
{
if (listHolder_mc._y + speed < mask_mc._y)
{
if (_mc.scrollFace._y <= top)
{
_mc.scrollFace._y = top;
}
else
{
_mc.scrollFace._y -= speed / moveVal;
}
listHolder_mc._y += speed;
}
else
{
_mc.scrollFace._y = top;
listHolder_mc._y = mask_mc._y;
delete this.onEnterFrame;
}
}
}
_mc.btnUp.onDragOut = function()
{
delete this.onEnterFrame;
}
_mc.btnUp.onRelease = function()
{
delete this.onEnterFrame;
}
_mc.btnDown.onPress = function()
{
this.onEnterFrame = function()
{
if ((listHolder_mc._y – speed) > finalContentPos)
{
if (_mc.scrollFace._y >= bottom)
{
_mc.scrollFace._y = bottom;
}
else
{
_mc.scrollFace._y += speed / moveVal;
}
listHolder_mc._y -= speed;
}
else
{
_mc.scrollFace._y = bottom;
listHolder_mc._y = finalContentPos;
delete this.onEnterFrame;
}
}
}
_mc.btnDown.onRelease = function()
{
delete this.onEnterFrame;
}
_mc.btnDown.onDragOut = function()
{
delete this.onEnterFrame;
}
if (contentHeight < maskHeight)
{
_mc._visible = false;
}
else
{
_mc._visible = true;
}
}
Once I had that modified, I needed to figure out when to call the function. First I called it right away. The first menu populates and at the end of my XML loader function I call the scrolling function to check to see if either list needs a scrollbar. Then, once one of the categories is selected (from list one), I needed to call the scrolling function again, checking to see if list two needs a scrollbar.
So, the first time I call it, inside my XML loader function, I am passing through the scrollbar for list one, the mask for list one and list one mc:
goScrolling(_root.theScrollbar1, _root.maskedView1, _root.listOneHolder);
The second time I call the function, inside my XML loader function, inside the onRelease function for my main menu (list one) nav i pass through the second list, mask and scrollbar:
_root.listOneHolder['myNav'+i].onRelease = function ()
{
goScrolling(_root.theScrollbar2, _root.maskedView2, _root.listTwoHolder);
}
I then had two functioning scrollbars! However, I have run into two problems … one of which I have solved, the other won’t take long but I have not yet done. I clicked on one of the main menu items. List two was long enough to have a scrollbar and I then scrolled to the bottom and selected one of the projects (or secondary menu items). When I went to another category, I realized list two did not reset itself. The _y property was still at the same value, as if I had used the scrollbar. SO. I added to the end of the scrolling function a short bit of logic:
// the number 55 represents the starting _y value
if (initContentPos < 55)
{
listHolder_mc._y = 55;
}
Here’s a link to the project as it is today. The second issue I found has to do with the mathematical calculation of height and/or how far down the scroll bar needs to go. The scroll current goes too far down, or rather, sets the _y property too low. So now I am off to fix that. I’ll post in the comments the solution when I have it.
Good luck!
A Position of Learning
On the brink of a total meltdown, I came to an enlightening realization yesterday. A few weeks ago I took on a Flash project that is very similar to several other projects I have done in the past. The task is to basically create a portfolio with categories and projects. When you click on a category, the project list is populated. Then, when a project is clicked, a box apears with the project title, description and image. For some reason I quoted the project on an hourly basis, rather than my typical project basis (this will come into play later on). I went back to my desk and decided I wanted to build the portfolio in ActionScript 3.0 instead of 2.0. The other similar portfolios I have built were all using AS 2.
After the design was finalized, I began to code. I quickly realized there could be a better way of coding, using a more modular approach and actually utilizing the principles of OOP (Object Oriented Programming … if you’re not techy, please negate all geeky words and phrases). These principles basically make it possible to reuse code. More work up front = less work in the long term. One of my goals this year is to become more efficient and knowledgeable in the realm of ActionScript and more specifically, OOP. My hope is that the new knowledge will improve my ability to teach and create, design and implement RIA (Rich Internet Applications).
Anyway, before this project I scheduled a one-on-one four hour tutoring session with Dana Payne, an ActionScript/Flex/Flash expert and Adobe Certified Instructor. Wednesday of this week I completed this tutoring session and felt like I had a handle on the principles we talked about. Dana was great and I intend to hire her again in a few months for a more intensive eight hour session. I highly recommend her to anyone looking to learn these things. So, yesterday when I sat down to implement what I had learned the day before in my current project, I struggled. I was stressed from other projects, on mind overload, and frustrated that this project was taking longer than I had anticipated, hence why the hourly quote was a shot in the foot. I do not charge for my learning experiences, however, I also did not anticipate spending four times the time on the project. It’s not about money … more about personal / professional proficiency (or lack there of).
At this moment of ultimate frustration, the realization hit me. It has been over a year and a half that I have been in this position of learning. Of course, I am not saying I have not learned anything in the last year and a half. Or that I have not been frustrated. Rather, it is that I decided to take my skills to the next level and in doing so, lacked the self preparation and patience to hit the exponential learning curve head on. As I sit here now, humbled and a bit more at ease, I recognize this things and am ready to be more patient with myself and my ability to learn.
Brand yourself or your business?
Just over a year ago I started my web design business. I was excited, enthusiastic and clueless. So badly did I want to start I didn’t take the time to slow down and assess what direction would be best. I moved quickly and rather than giving my business a name, I registered Erin N Pierce, LLC. Boooooring.
One year later, I am striving to take on larger projects, bigger clients and growing out of my single person shop. It is time to rename, or rather, name my business. The biggest obstical is how to name it with out having to rebrand. I have a few ideas in mind and checked with the State and the interweb to make sure they are available. Once I land on something catchy and awesome, I’ll let you know! In the meantime, if you have any suggestions, post a comment below.