views:

1306

answers:

5

Can anyone help me decode why this doesnt work?

$cssid = preg_replace("/'/", "", $cssid);

Trying to strip the single quote marks from some html...

Thanks! H

EDIT This is the full function - it's designed to rebuild the Drupal menu using images, and it applies CSS classes to each item, allowing you to select the image you want. Stripping out spaces and apostrophes needs to be done or the CSS selector fails.

The title of the menu item causing all this problem is:

What's new

Pretty innocuous you'd think. (Except for that single ')

function primary_links_add_icons() {
  $links = menu_primary_links();
  $level_tmp = explode('-', key($links));
  $level = $level_tmp[0];
  $output = "<ul class=\"links-$level\">\n";   
  if ($links) {
    foreach ($links as $link) {
        $link = l($link['title'], $link['href'], $link['attributes'], $link['query'], $link['fragment']);
        $cssid = str_replace(' ', '_', strip_tags($link));
     $cssid = str_replace('\'', '', $cssid);
     /*$link = preg_replace('#(<a.*?>).*?(</a>)#', '$1$2', $link);*/
     $output .= '<li id="'.$cssid.'">' . $link .'</li>';
    };
    $output .= '</ul>';
  }
  return $output;
}

EDIT the saga continues...

I notice that I get the following error in PHPMYADMIN:

The mbstring PHP extension was not found and you seem to be using a multibyte charset. Without the mbstring extension phpMyAdmin is unable to split strings correctly and it may result in unexpected results.

I wonder whether this has something to do with it?

In any case the the SQL code is:

('primary-links', 951, 0, 'http://www.google.com', '', 'What''s New',

And this displays in FireBug once it's been rendered as:

<li id="What's_New">

I've created a menu item called "What@s New" and the str_replace() will work on that just fine, so it's ALL about this goddam apostrophe. I think I agree, the expression works, but it has to be an encoding problem. It really is a proper, common, apostrophe and not one of the variants, but for some reason PHP is absolutely unable to recognise it as such.

EDIT oh god oh god - it's Drupal again... It appears that the function l() which formats all the links is completely impervious to having it's output rewritten?! Whatever the case, this code works...

function primary_links_add_icons() {
  $links = menu_primary_links();
  $level_tmp = explode('-', key($links));
  $level = $level_tmp[0];
  $output = "<ul class=\"links-$level\">\n";   
  if ($links) {
    foreach ($links as $link) {
        $link['title'] = str_replace('\'', '', $link['title']);
     $link = l($link['title'], $link['href'], $link['attributes'], $link['query'], $link['fragment']);
        $cssid = str_replace(' ', '_', strip_tags($link));  
     /*$link = preg_replace('#(<a.*?>).*?(</a>)#', '$1$2', $link);*/
     $output .= '<li id="'.$cssid.'">' . $link .'</li>';
    };
    $output .= '</ul>';
  }
  return $output;
}

2 hours later and I can carry on theming this site...

Thank you so much for all your suggestions, I'm going to point the drupal snippet authors at this post so hopefully other people will benefit from it too.

+1  A: 

Your code looks fine. But why don’t you use str_replace as you’re replacing a fixed string?

$cssid = str_replace("'", "", $cssid);
Gumbo
mainly because that doesnt work either :) It's been bugging the hell out of me for half an hour and stopping me from finishing my work :x
hfidgen
@hfidgen: THen you’re probably doing something wrong.
Gumbo
You sir are a genius. Why didn't I think of that. If I had, I might have come and posted on... oh wait.
hfidgen
+2  A: 

escape the single quote.

MiRAGe
still no... I've tried damn near every combination I can think of. This is driving me mad!
hfidgen
$cssid = str_replace('\'', '', $cssid); should definitely work.. unless there's something different in your php.ini?
MiRAGe
Still no :( I'm perfectly prepared to believe it's the PHP ini - this is being developed on a IIS system run by FastHosts.com and they are f*cking terrible. Hosting aside, any other ideas?
hfidgen
I just confirmed that it works when using single quotes only.
MiRAGe
I used this code; $string = "<body onload='test'>";$string = str_replace('\'',"-",$string);
MiRAGe
I just tried this in my page body and it works. So it's something out there in the function which is mucking this up: $string = "<p>this is'a test' example</p>"; $string = str_replace('\'',"-",$string); echo $string;
hfidgen
+1  A: 

If str_replace("'","") doesn't work, are you sure the characters you want to remove are indeed normal apostrophes (') instead of weird alternatives (’), or some weird accent marks (´`˙ ̛̉῾᾿) or single quotes (‘’) or whatnot?

Or maybe the value of $cssid gets replaced back to original by some other bug?

Maybe you're looking at the wrong output for results?

Or by a far chance, are you accidentally running a different copy of the code than the one you are editing - btw, that's really annoying when it happens! :)

Ilari Kajaste
haha yeah that occurred to me too - as far as I'm able to see it is indeed a plain old apostrophe and none of the alternatives. cssid is also a completely made up variable, so it's not getting replaced anywhere. And yeah, this code is getting published correctly :D
hfidgen
To be sure it's the correct character, you could try `file_put_contents('debug.txt',$cssid)` and copy the character from the debug.txt to your code, see if that works...
Ilari Kajaste
Or, ehm, easier check would be to force `$cssid = "What's new"` before the replace, and check if that works... (It'll affect every list item of course, but for debug it shoudln't matter.)
Ilari Kajaste
+1  A: 

Given that it is HTML have you considered that it may be represented as &#39 rather than '?

Yacoby
Good idea! But no :(
hfidgen
+2  A: 

CSS image replacement is a much more commonly chosen way for menu item replacing:

First install: Menu Attributes module to be able to assing css id's for every menu item. (these attributes can be set from the menu item edit page on admin panel)

Then use css image replacement. Here is a good tutorial for this.

And this is the method i use for my sites:

    #primary-tv
{
    display: block;
    width: 90px;
    height: 0px;
    padding-top: 41px;
    background: url(images/nghtv.png);
}

This is an example for replacement with an image of 90 x 41px

And for the apostrophe replacement:

$cssid = preg_replace("&#039;","",htmlspecialchars($cssid, ENT_QUOTES));
hecatomber
You know, I WISH Drupal.org would have stuff like this just laid out. It's one of the best, yet conversely WORST documented CMS's i've used :( Thanks for the tip though, that looks great!
hfidgen
That works perfectly! Question answered!
hfidgen
Documentation is a hard work and drupal.org has too many content so it's harder to document everything. I also heard some work on Lullabot podcast about documentation problem. I'm sure that we can't find solution to our every problems, but new Drupal Search which is powered by Apache Solr and the Issue system helps. ( also I mostly use "google search" with site:drupal.org parameter for my drupal queries :) )
hecatomber
yeah I know what you mean. But surely there's got to be a "install these modules to make a nice CMS" article out there :P
hfidgen