1

I have spammed many duplicate posts from one initial and now after editing them the url structure for them is something like http://example.com/base-name-copy-20 where base-name is the slug of the duplicated initial post. Now, I could change the permalink for every one of them manually I know, but is there a way to create a slug for those duplicated posts anew ? I have edited them so they all have their own title now, but the permalink is already set. If I could reassign the permalinks the same way that wordpress automatically gives a slug for them initially would be nice.

Thanks in advance !

1

Editing the permalink manually would be the safest route. If you're comfortable using phpMyAdmin, you could create a MySQL query to update them all in one batch. Slightly more work than auto-assigning a slug, but it doesn't require a lot of coding to try to re-calculate the slugs.

update wp_posts SET post_name = 'new-slug' WHERE post_name = 'old-slug';

(You can copy and paste this onto multiple lines and update as many as you like in one operation.)

  • Thank you for pointing me in the right direction, I have searched further and perfected my script to solve my case :) – George Dimitriadis Feb 21 '17 at 8:41
  • Cool, perhaps you can edit the answer above to help others and mark as solved :) – WebElaine Feb 21 '17 at 20:13
  • I already posted my full solution, but can't mark it yet due to the 24 hours limitation. – George Dimitriadis Feb 22 '17 at 13:51
1

After finding some interesting sources I ended up with this solution (added an extra function to take care of a few Dutch characters as well):

drop function if exists fn_remove_accents;
delimiter |
create function fn_remove_accents( textvalue varchar(20000) )
returns varchar(20000)
begin

set @textvalue = textvalue;

-- ACCENTS
set @withaccents = 'ŠšŽžÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÑÒÓÔÕÖØÙÚÛÜÝŸÞàáâãäåæçèéêëìíîïñòóôõöøùúûüýÿþƒ';
set @withoutaccents = 'SsZzAAAAAAACEEEEIIIINOOOOOOUUUUYYBaaaaaaaceeeeiiiinoooooouuuuyybf';
set @count = length(@withaccents);

while @count > 0 do
    set @textvalue = replace(@textvalue, substring(@withaccents, @count, 1), substring(@withoutaccents, @count, 1));
    set @count = @count - 1;
end while;

-- SPECIAL CHARS
set @special = '!@#$%¨&*()_+=§¹²³£¢¬"`´{[^~}]<,>.:;?/°ºª+*|\\''';
set @count = length(@special);
while @count > 0 do
    set @textvalue = replace(@textvalue, substring(@special, @count, 1), '');
    set @count = @count - 1;
end while;

return @textvalue;

end
|

DROP FUNCTION IF EXISTS `slugify`;
DELIMITER ;;
CREATE DEFINER=`root`@`localhost` # I have no idea what this does
FUNCTION `slugify`(dirty_string varchar(200))
RETURNS varchar(200) CHARSET latin1
DETERMINISTIC
BEGIN
    DECLARE x, y , z Int;
    Declare temp_string, allowed_chars, new_string VarChar(200);
    Declare is_allowed Bool;
    Declare c, check_char VarChar(1);

    set allowed_chars = "abcdefghijklmnopqrstuvwxyz0123456789-";
    set temp_string = fn_remove_accents(LOWER(dirty_string));
    Select temp_string Regexp('&') Into x;
    If x = 1 Then
        Set temp_string = replace(temp_string, '&', ' and ');
    End If;

    Select temp_string Regexp('[^a-z0-9]+') into x;
    If x = 1 then
        set z = 1;
        While z <= Char_length(temp_string) Do
            Set c = Substring(temp_string, z, 1);
            Set is_allowed = False;
            Set y = 1;
            Inner_Check: While y <= Char_length(allowed_chars) Do
                If (strCmp(ascii(Substring(allowed_chars,y,1)), Ascii(c)) = 0) Then
                    Set is_allowed = True;
                    Leave Inner_Check;
                End If;
                Set y = y + 1;
            End While;
            If is_allowed = False Then
                Set temp_string = Replace(temp_string, c, '-');
            End If;

            set z = z + 1;
        End While;
    End If;

    Select temp_string Regexp("^-|-$|'") into x;
    If x = 1 Then
        Set temp_string = Replace(temp_string, "'", '');
        Set z = Char_length(temp_string);
        Set y = Char_length(temp_string);
        Dash_check: While z > 1 Do
            If Strcmp(SubString(temp_string, -1, 1), '-') = 0 Then
                Set temp_string = Substring(temp_string,1, y-1);
                Set y = y - 1;
            Else
                Leave Dash_check;
            End If;
            Set z = z - 1;
        End While;
    End If;

    Repeat
        Select temp_string Regexp("--") into x;
        If x = 1 Then
            Set temp_string = Replace(temp_string, "--", "-");
        End If;
    Until x <> 1 End Repeat;

    Return temp_string;
END;;
DELIMITER ;

UPDATE wp_posts SET post_name = slugify(post_title) WHERE post_name LIKE '%copy%' AND post_type = 'MY_POST_TYPE';

Explaining the query: The first two functions are directly taken from sources 1 and 2, with a small edit to handle uppercase characters too.

Finally the update query will match on those duplicated posts that have the word copy in their slug, but depending on your case, you probably want to make this rule more strict. I want to run this query on my custom post type, so I added an extra check for the post type on the query, not a big deal.

The matched posts will be assigned a newly generated slug based on their title (post_title), alternatively you can specify a different source for the slug generation.

Sources:

[1] Replace non-latin characters selectively

[2] Regenerate a slug from a free-text name

[3] WebElaine's answer (on this page)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.