I have had this problem for a while,
Let say we have a movies website
And we have a movie named Test-movies123! in the database,
now what I would do is make a URL watch/test-movie123-{$id}/ and then query DB with the ID,
Now the issue with this is that the ID shouldn't be there, how can I go around this ?
if I get the test-movie123 from url and search it, I wont find it because it has no ! unless I use LIKE but thats not very trusty...
Anyone could suggest anything ? Would be much appreciated
Well, you could create a rule for taking the movie title and turning it into a slug. So, you'd know that you always lowercased the title, removed anything other than letters, numbers and dashes, and converted whitespace into a single dash.
Then store that in another column in your database, and be sure you are forcing uniqueness. Take the URL and search that column from that.
From that point you just have to deal with what happens if you have a second video uploaded that produces the exact same slug. There are a number of options for this ... append a random number slug, increment a number and append it, etc.
To do that, you may have in your database something like the primary_key as
"test-movies123".
Imagine you have a control panel, you insert movies in a form.
Then use the title Test Movies123! to save it in the database like this example:
id: AUTO_INCREMENT NUMBER
keyname: sanityTitle("Test Movies123!") <-- this should save "test-movies123"
title: "Test Movies123!"
stuff: "blablabla"
note sanityTitle() will be your function to prepare friendly url's from titles.
Then your url will look like
watch/test-movie123/ using regex control in url's
or
watch/?id=test-movie123 raw
You will search for the INDEXED or PRIMARY key, "keyname" in the table, it will output 1 row, with all your stuff.
Related
I have URL like base_url()/controller/rowtitle-rowid.
Where this URL is manipulated using function and arranged according to row in database.
As mentioned above I need to change whole URL when I am changing rowid in the URL, that means it should rewrite to particular id of row in database.
For example:
Consider following URLs
https://www.marketsandmarkets.com/Market-Reports/medical-device-testing-market-254474064.html
2.https://www.marketsandmarkets.com/Market-Reports/timing-relay-market-241993160.html
if I change bold numbers in number 2 URL to bold numbers in number 1 URL then it will rewrite the URL to URL number 1 and redirect to URL number 1
Can this possible?
Thanks in advance.
Your say you are modifying the rowid which I assume are the numbers you are bolding in your 1,2 statements, and at the same time you want to redirect to a different slug and rowid which is the dashed statement before the rowid at the end of the url e.g. some-page-name.
I'm not sure what the rowid has to do with anything, perhaps it's just a random int to make sure you don't have duplicate slugs, but it isn't strictly required as long as you increment your titles if you have duplicates like some-page-name and some-page-name-1.
In PHP and codeigniter what you are trying to do is indeed possible as long as you keep a database with all the iterations of the slug. Then in your Market-Reports controller you just look for the most recent iteration of the slug and serve that as a link to the user. Or if the user is coming from a search engine, on the say Market-Reports single page controller to timing-relay-market-241993160 you query the database where rowid = 'someid' and order by created or something and then redirect the user to that slug which would be medical-device-testing-market-254474064.
Further if your database table for keeping track of slugs has the following rows rowid, rowtitle, fullslug you could literally just use intval() to get the rowid from the fullslug and do the same type of thing as I just outlined in the previous paragraph.
NOTE: You cannot do this with static HTML pages. I am assuming since you tagged PHP and codeigniter you are using php and controllers.
I have a website that I want to start using friendly URLs.
So instead of:
http://server.com/company.php?id=12
I could use:
http://server.com/company/steaks_r_us
I know how to do this on the .htaccess side, but I don't know how to set it up on the backend with the database calls, especially if there is a chance that company name isn't unique (multiple locations for instance).
I've thought about inserting the friendly url into the database after checking for duplicates, but I'm curious if there is a better way
No matter if it's an ID or a user friendly string like company name, you need it to be a unique identifier. You won't avoid that.
There are couple of options.
Some websites adds ID (primary key) to the user friendly name like:
http://server.com/company/steaks_r_us_12
or in other part of URL like:
http://server.com/company/12/steaks_r_us
Then you can easily fetch the ID from the URL, but also it still looks nice.
Also as wheatin suggested, you could create a field in your DB that would be this unique identifier.
In this case you would need some additional logic at the time of creation of company row in database. That's of course because you have to handle duplicated names somehow.You could for example add a digit at the and of this value (facebook does something like that), so if a duplicate of steaks_r_us occurs, you would insert a value steaks_r_us2
Then you would have unique URL for these companies:
http://server.com/company/steaks_r_us
and
http://server.com/company/steaks_r_us2
You could create a unique index on the business key (in this case the company name) to prevent duplicates from being inserted in the first place.
Wheatin has the right idea. You'd want to have a table with two columns, the URL and the id it's referring to. If you made a unique key on the URL column, then you could just have a function/method that tries to insert the clean URL with the content id; I usually do something like
###(pseudocode)
function create_unique_url($url, $id) {
try to insert the url, id combination
if success:
return url
else:
key = 1
start a loop
try to insert the url+key, id combination
if success:
return url
key++
}
Adding a number to the end is a good fail-safe way to make sure you always get a unique url returned. Sort of how Drupal or Wordpress would handle a post url with an identical name.
I have a database containing a table named songs with a field title.
Now If my url is http://www.foo.com/songs/xxx (xxx = the title of the song),
apache is silently redirecting to a page that looks similar to : /song.php?title=xxx.
To embellish the URLs I convert spaces into underscores (cause I know some browser display %20 instead of space, not%20really%20user%20friendly%20ya%20know%20what%20i%20mean).
There's a snag cause if the title contains spaces and underscores (e.g. DJ_underscore fx) and the script converts it into DJ_underscore_fx the sql :
select * from songs where songs.title=xxx
can't find it.
here's the sketch to be more specific:
a script fetches the different titles in the database
converts all the space into underscore ( e.g. name_of the song ->
name_of_the_song )
echo them as links ( e.g. name_of_the_song )
the user clicks on the link and requests the document
apache is silently redirecting ( e.g. /songs/name_of_the_son ->
/song.php?title=name_of_the_song )
song.php fetches the specific data ( e.g. select * from songs where songs.title=name_of_the_song )
ok you see that there's no entry in the database that looks like name_of_the_song but name_of the song.
How can I manage the whole so that my URL remains clear and the title field is not restricted to a certain amount of values (can have spaces, underscore, dashes, well anything)?
Use something like /1234/name-of-page/ where 1234 is the primary key ID of the row and name-of-page is ignored by your script.
This gives a link directly to the primary key of the entry in the table, which will give you several benefits:
No need to have duplicate ID fields.
Fast indexing on SELECT queries.
You still get the readability and SEO benefits of a "pretty" URL.
You might notice that StackOverflow itself does exactly this:
/questions/8211267/user-friendly-urls-reliable-with-the-database/
Which probably gets re-written to something like:
question.php?id=8211267
Just add another field that will keep the exact name used in URL. And when you have some "duplicates" - just append them with _2, _3 etc or give a way for user to edit and give another name manually.
What your trying to achieve is definetly the wrong way, you could have hundreds of variations to lookup in your database and is also bad for SEO.
Start by setting a rule that all URL's have _ to seperate the space, that's how most site URL's are done (digg.com being an example).
Then create a seperate field that stores the URL e.g.
title | url
song name | song_name
Then do your lookup based on the URL field.
For legacy reasons you could also replace any spaces with _ in your lookup script when you receive the title from the GET before doing the database query.
well, if you want spaces in the url, people will have it uri encoded for transit. if rather than replacing all _ with spaces, just use a uridecoder (can't remember the exact title). it would still allow for spaces to be typed. On the displayer, the shown text in the link, cant you do an str_replace to convert %20 in spaces?
Either that of have a computer friendly version of the title (that doesn't use spaces, but underscores) and a user friendly column that does have the spaces
I'm making a news system that uses unique slugs to identify the article. When creating a new article, I need to make sure the unique slug is not already in use. So if two articles have the exact same name, they will therefore generate the exact same slug. I want to append a number to the end of the slug in the event it is in use.
Like so:
some-really-interesting-article
some-really-interesting-article-1
some-really-interesting-article-2
And so on. So in my test case, I'm selecting all records from the database that exactly match "some-really-interesting-article" with 0 or more "-number". So in this case I will return 3 rows, so the next slug would be "some-really-interesting-article-3".
This works great except my regex is behaving peculiar (or likely very normal, and I just suck at regex) and is also return rows with partial matches. So if I search "some-really-interesting", that will pass.
SELECT id, title, slug
FROM news
WHERE slug RLIKE '([[:<:]]some-really-interesting-article[[:>:]][-\d]*)'
So as I said, if I run the above regex with "some-really-interesting" it will return all 3 rows.
Please tell me that I am blatantly and ignorantly doing wrong. Thanks.
What about this ?
"^some-really-interesting-article(-[[:digit:]]+)?$"
Hopefully this will work :)
Try
WHERE slug RLIKE '(^some-really-interesting-article(-[0-9]+)?$)'
As others have already noted, this will work:
SELECT id, title, slug FROM news
WHERE slug RLIKE '^some-really-interesting-article(-[0-9]+)?$'
However, MySQL is not smart enough to make good use of indexes with RLIKE. (If you have an index on the slug column, it may try to use it, but will have to do a full index scan.) It turns out, though, that you can use a redundant LIKE condition to help MySQL handle the query more efficiently, like this:
SELECT id, title, slug FROM news
WHERE slug LIKE 'some-really-interesting-article%'
AND slug RLIKE '^some-really-interesting-article(-[0-9]+)?$'
The LIKE query might match some false positives, like some-really-interesting-article-about-something-else-entirely, but the RLIKE will weed them out. Of course, if you don't care about such false positives, you could leave out the RLIKE entirely.
Of course, another possibility would be to create a unique index on the slug column (which you really should have anyway) and just keep incrementing the slug and trying to insert the record until the INSERT succeeds. Of course, that also means you should check the error code and message to see why it fails if it does. (If an INSERT fails because of a duplicate value, the error code should be 1062 and the error message should contain the name of the duplicate key.)
Anyway, here an SQLize link if you want to play with the query; I left some comments in it.
could someone please point me in the right direction, I currently have a searchable database and ran into the problem of searching by title.
If the title begins with "The" then obviously the title will be in the 'T' section, what is a good way to avoid "The" being searched ? Should i concat two fields to display the title but search by only the second title ignoring the prefix. or is there another way to do this? Advice or direction would be great. thanks.
A few choices:
a) Store the title in "Library" format, which means you process the title and store it as
Scarlet Pimpernel, The
Tale of Two Cities, A
b) Store the original unchanged title for display purposes, and add a new "library_title" field to store the processed version from a).
c) Add a new field to store the articles, and the bare title in title field. For display, you'd concatenate the two fields, for searching you'd just look in the title field.
I believe the best approach is to use full-text search, with 'the' in the stopwords list. That would solve the search problem (i.e., 'the' on search phrases would be ignored).
However, if you are ordering the results by title, a title starting with 'The' would still be sorted, "in the 'T' section", as you put it. To solve that, there are several possible approaches. Here are some of them:
Separating the fields, the way you said on the quesiton
Having a separate field with the number of chars to be ignored from the beginning when sorting
Replacing initial 'The's for sorting
Among others...
If you are using mysql, you could use a str_replace function to remove "The" from your query, or if you are using PHP or Ruby or another language you can just sanitize your query before sending to the database server.
Create three columns in the database
1) TitlePrefix
2) Title
3) TitlePostfix
Code such that you have 4 methods like
searchTitleOnly(testToSearch) // search only title column
searchTitleWithPrefixAndPostfix(testToSearch)//concat all the three columns and search
searchTitlePrefix(testToSearch) // search title prefix only
searchTitlePostfix(testToSearch) // search title postfix only
Try looking into some sql functions like LTRIM, RTRIM etc and use these functions on a temp column which has exact same data. Modify the data by using LTRIM, RTRIM by dropping whichever words u please. Then perform the search on the modified column and return the entire row as the result!