开发者

I know views and controllers shouldn't share logic.. but how else can I do this?

开发者 https://www.devze.com 2023-01-29 13:04 出处:网络
I have a controller called DesignersController, the index method lists them and the view method accepts the designer name as a parameter and retrieves it by name.

I have a controller called DesignersController, the index method lists them and the view method accepts the designer name as a parameter and retrieves it by name.

so /designers will list all the designers and /designers/view/designer-name will display that designer.

Now if a designer name has a space, it needs to be escaped in the URL. I have logic for escaping and unescaping the spaces:

private $space_escape_char = '-';

function escapeSpaces($str) 
{        
    return str_replace(" ",$this->space_escape_char,$str);    
}

function unescapeSpaces($str) 
{        
    return str_replace($this->space_escape_char," ",$str);    
}

Now the view method on the Controller needs access to this so when it's passed a name like "Foo-Bar" it can translate that into "Foo Bar".

The index.ctp view file also needs acces开发者_运维技巧s to it, so when it lists all the designers it can give links to each one, and be able to escape each name:

<?php foreach ($designers as $designer): ?>    

<div>
<?php 
    echo $this->Html->link(
        $designer['Designer']['name'], 
        array(
            'controller' => 'designers', 
            'action' => 'view', 
            escapeSpaces($designer['Designer']['name'])
        )
    ); 
?>
</div>

<?php endforeach; ?>

What is the best way to handle this without code duplication?


The usual way this is done is to put the primary ID of the entity in the URL and have the name/title (in your case designer name) in the URL for keywords/usability.

For example

/designers/view/13/designer-name/

The controller will only care about the 13, searching the database for the designer of ID 13. It wouldn't use designer-name at all.

This is the way it's done here on Stackoverflow.

It also prevents /designers/view/john-smith12/


What you're doing here is converting the designers' names into slugs, but manually. What you can do instead is use a Behaviour (like this Sluggable Behavior) to store the slug of your designer's name automagically. Thereafter, you can refer to $designer['Designer']['slug'] wherever you want the URL-safe version of the name. This slug gets stored in the database as part of the model data, so you can even query against it.


If this is a common occurance, I would recommend storing a URL slug in the the users database entry. Calculate it once, and re-use it from there. Why recalculate something that will be the same every time?

0

精彩评论

暂无评论...
验证码 换一张
取 消