Forum Moderators: coopster

Message Too Old, No Replies

Script which displays subjects on a web page sorted by year (not date)

Need help finding a script which does a very specific thing

         

Mabus

10:15 pm on Jul 13, 2010 (gmt 0)

10+ Year Member



Hi there, I'm not sure if this is the right place to post this but here goes.

I'm trying to create a website which will list events as a timeline (preferably as a simple html page). For example;

143 BC <Ruler XYZ> <Rome> <Europe> ruler XYZ invaded Rome
294 <Inventions> <Harold IX> <Europe> the whatchamacallit was invented by Harold IX
312 <Ewoks> <Rome> <Europe> The Ewoks Sacked Rome

etc...

Now here's what I need, a script that I can set to work on tags so that I can create a webpage for specific subjects. For example;

index.php

<Rome>

143 BC ruler XYZ invaded Rome
312 The Ewoks Sacked Rome

As you can see, this script only looked for items on the full database list which are marked <Rome> and only printed those items on the page, and then listed them in order by year (not by date inputted).

Does anyone know of any script that does anything remotely like that?

Mabus

11:35 pm on Jul 13, 2010 (gmt 0)

10+ Year Member



Just to clarify a bit.

I want to create a static text or html database with ALL my information, listing the year of the event, some subject tags, and then the event itself

Then I want to have a script which allows me to pull out only the events with that particular tag, in the order of the year it happened (and not the date i added it to the database).

So for example, I could create a database of global events, and then have seperate pages running the script, which would automatically pull out the events by subject.

That way, I could just add every event to a single database, and it would automatically update every page with the information, without having to manually change every single page.

Mabus

8:59 pm on Jul 14, 2010 (gmt 0)

10+ Year Member



I've added a test database page to show what I mean exactly;

[dalnetdebates.com ]

As you can see, events are listed by date and in the source code of the html page, each line is tagged with a <rem Subject> tag for sorting.

Mabus

4:12 pm on Jul 16, 2010 (gmt 0)

10+ Year Member



No replies as yet, let's try this then;'

I want to create an html (or php) page with a series of lines, and at the start of each line have a series of tags. I need for the script to sort through a list, seek out only the lines with the specific tag, and then create a new page with only those tags. Example;

<apple> <strawberry> recipe for apple tart
<grape> <strawberry> grape juice roll
<apple> <cinamon> apple cinamon roll

The script should sort through the above list, pick out only the lines with the tag <apple> in it and creating a new html page which only the lines with the right tag in it. Example;

<html>
<head>
</head>
<body>
<table>
<tr>
<td>
recipe for apple tart <br>
apple cinamon roll<br>
</td>
</tr>
</body>

Any help?

rocknbil

5:15 pm on Jul 16, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You haven't gotten any replies because no one seems to understand the problem, including me. :-) But welcome aboard, let's see what we have here . . .

Why do you need these tags in the page or in the content itself? A standard way of approaching keyword tagging (if that's what you're doing) is to use a relational table, which allows multiple tags for any given resource. Using your original example,

143 BC <Ruler XYZ> <Rome> <Europe> ruler XYZ invaded Rome
294 <Inventions> <Harold IX> <Europe> the whatchamacallit was invented by Harold IX
312 <Ewoks> <Rome> <Europe> The Ewoks Sacked Rome

This gives you

table articles (or whatever)
id|article_id|year|anno_domino|description
1|1234|143|BC|ruler XYZ invaded Rome
2|1235|294|AD|the whatchamacallit was invented by Harold IX
3|1236|312|AD|The Ewoks Sacked Rome

table tags
id|tag_id|article_id|tag_content
1|987|1234|Ruler XYZ
2|988|1234|Rome
3|989|1235|Europe
4|990|1235|Inventions
5|991|1235|Harold IX
6|992|1235|Europe
7|993|1236|Ewoks
8|994|1236|Rome
9|995|1236|Europe

. . . on which you can perform any variety of selects joining the tables. Note in particular the join on the article_id column in both tables.

In truth, this is not a "fully normalized" solution, note how there are multiple entries with Rome, Europe, and potentially others. You'd probably want to join on three tables, the third connecting the unique values in tags with the unique values in articles.

This has several advantages, your data is open in a table structure instead of mucked up inside your content. It also allows you to output valid code, although presentationally <Rome> is invisible, it's invalid code. The only practical application is via XHTML with a custom document definition and it would take the form of <Rome>Rome</Rome> (and I'm still not seeing the benefit of that. :-) )

If you need those tags in your content for some reason, you can still put it there by selecting it from the tables, but it allows you to search more efficiently on the clean textual values in the tables.

We can explore this more if it sounds like it might work for you.

Mabus

8:44 pm on Jul 16, 2010 (gmt 0)

10+ Year Member



Thanks for the reply Rocknbil :)

That's an interesting idea, the problem is that I would be forced to add events in a descending fashion and not sequentially by year. News events and archeological discoveries are being made all the time. Let me illustrate what I mean.

table articles (or whatever)
id|article_id|year|anno_domino|description
1|1234|143|BC|ruler XYZ invaded Rome
2|1235|294|AD|the whatchamacallit was invented by Harold IX
3|1236|312|AD|The Ewoks Sacked Rome
4|1237|123|AD|Ewoks arrive in europe
5|1238|200|BC|Rome is founded by Spock

Notice how new information is added on, but the years are not sequential. Doing it this way though makes it much more of a challenge for me, because as you can imagine the list would not have any order whatsoever (chronologically). We'd be going from the big bang, to information on the assassination of caesar, and back to the formation of the earth. That would quickly become unmanageable.

Doing it the way I suggested earlier, allows me to go in and manually edit the list (without numbering the articles sequentially) to give the master database a sequential list sorted by year. I hope you see what I mean there.

Whatever the solution is, I think it would need me to have a master list that is sequential.

Readie

8:57 pm on Jul 16, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hmm...

The problem here is the year order needs to be switched between ASC/DESC depending on the year being AD/BC I believe?

If so, I the UNION ALL command should suffice here:

$sql = '
SELECT * FROM articles WHERE anno_domino = "AD" ORDER BY `year` DESC
UNION ALL
SELECT * FROM articles WHERE anno_domino = "BC" ORDER BY `year` ASC
';
$result = mysql_squery($sql);

// Continue script...

Mabus

9:35 pm on Jul 16, 2010 (gmt 0)

10+ Year Member



Wouldn't it just be easier to include the year into the line of text and not worry about it?

How would this work?

table articles (or whatever)
id|article_id| full line of text
1|1234| 143 BC ruler XYZ invaded Rome
2|1235| 294 AD the whatchamacallit was invented by Harold IX
3|1236| 312 AD The Ewoks Sacked Rome
4|1237| 123 AD Ewoks arrive in europe
5|1238| 200 BC Rome is founded by Spock

Readie

11:00 pm on Jul 16, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Again: You have the problem with needing to reverse the numerical order of "year" when jumping from AD to BC.

Another option that just occured to me though, have the year as a signed INT field, BC can then be negative numbers, and your PHP script can sort out the formatting afterwards.

Mabus

5:48 pm on Jul 17, 2010 (gmt 0)

10+ Year Member



I'm not sure why.....

Let me try to explain this another way that perhaps may clear things up. The main database text file should look something like this (this may be clearer)

<tag 1><tag 2> random text 1
<tag 2><tag 3> random text 2
<tag 1><tag 3> random text 3

So for example, I could config the script to look for tag 1 and it would give me this page;

random text 1
random text 3

So as you can see..... the year should not matter really as it's just part of the text.

Readie

7:00 pm on Jul 17, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Well, consider the following:

352 BC...
229 AD...
500 BC...
875 AD...
953 BC...

SQL:
SELECT * FROM articles ORDER BY random_text DESC

New order:
953 BC...
875 AD...
500 BC...
352 BC...
229 AD...

Which are clearly not chronologically ordered.

Yes, if you want to completley split by AD/BC, your method would work, but I don't see why you should want to - people may want to see all events between 100 BC and 100 AD on one page - why limit them when it's so easy to accomodate them?

Mabus

7:21 pm on Jul 17, 2010 (gmt 0)

10+ Year Member



I think we should just forget the years and dates, that seems to be causing a ton of confusion. This is exactly what I want to do;

I want to have a page that has all my information on a text page (this is absolutely pivotal, I cannot do what I want with a database). I can do this on my own with simple notepad (or an html editor)

<tag 1><tag 2> line of text 1
<tag 2><tag 3> line of text 2
<tag 1><tag 3> line of text 3

Once that's done, I want to have a script (and this is where I need help), that combs through the text page for lines with the text <tag 1>

Once it's found lines with <tag 1> it needs to build a new web page (html/php) with the following text

line of text 1
line of text 2

Note that it searches for a specific tag
Note that it ignores all other tags
Note that it builds a new page that includes only the lines of text which contained the specific tag.

Readie

7:58 pm on Jul 17, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Oh, in that case:

$input = 'tag1';
$input = preg_quote($input);
if(preg_match_all('/[^\r\n]*' . $input . '[^\r\n]*/im', $text_to_search, $out)) {
$output = ucfirst(strtolower($input)) . '<br>';
$rows = count($out);
for($i = 0; $i < $rows; $i++) {
$output .= '<br>' . $out[$i][0];
}
$new_file_name = preg_replace('/[^a-z\d_\-]+/', '', $input) . '.html';
$file = fopen(rtrim($_SERVER['DOCUMENT_ROOT'], "/") . '/path/to/file/' . $new_file_name, 'wb');
fwrite($file, $output);
fclose($file);
}

Should do what you're after.

Bear in mind I've typed this on the fly so it might not be working code.

rocknbil

8:40 pm on Jul 17, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I've been away . . . . the overall assessment, you're making life very hard for yourself if you rely on sarching within that block of text for tags. A few highlights,

Notice how new information is added on, but the years are not sequential.


Right, this is where the power of mysql comes in and why I demonstrated an AD/BC column. as Readie says, this allows you to order the results however you want with a few simple changes in your order by clause. This basic data structure would allow you to do that, working example below.

Wouldn't it just be easier to include the year into the line of text and not worry about it?


By putting it into the text, you're locking yourself into the very problem you describe, and the order of the records becomes relevant, whereas with separate columns, you can get a variety of result orderings by a simple rearrancement of the select statement. What you don't appear to be seeing is your requirements for this data may change as it grows, and as much as you can normalize in the underlying structure will make for more painless transitions as it does.

Intrigued by the overall question, here's a little test I put together using my example, you should be able to recreate it and run the below tests via command line or phpMyAdmin. Note I threw them out of order in the insert to verify the correctness when selecting.

create table articles (id int(11) primary key auto_increment, article_id int(11), year int(4), anno_domino char (2) not null default 'AD', description varchar(255));

insert into articles (article_id,year,anno_domino,description) values ('1234','143','BC','ruler XYZ invaded Rome');
insert into articles (article_id,year,anno_domino,description) values ('1235','294','AD','the whatchamacallit was invented by Harold IX');
insert into articles (article_id,year,anno_domino,description) values ('1236','312','AD','The Ewoks Sacked Rome');
insert into articles (article_id,year,anno_domino,description) values ('1237','64','BC','rocknbil pillages brewery');

create table tags (id int(11) primary key auto_increment, tag_id int(11), article_id int(11), tag_content varchar(255));

insert into tags (tag_id,article_id,tag_content) values ('987','1234','Ruler XYZ');
insert into tags (tag_id,article_id,tag_content) values ('988','1234','Rome');
insert into tags (tag_id,article_id,tag_content) values ('989','1235','Europe');
insert into tags (tag_id,article_id,tag_content) values ('24','1237','art of beer');
insert into tags (tag_id,article_id,tag_content) values ('993','1236','Ewoks');
insert into tags (tag_id,article_id,tag_content) values ('994','1236','Rome');
insert into tags (tag_id,article_id,tag_content) values ('995','1236','Europe');
insert into tags (tag_id,article_id,tag_content) values ('13','1237','conquering hangovers');
insert into tags (tag_id,article_id,tag_content) values ('990','1235','Inventions');
insert into tags (tag_id,article_id,tag_content) values ('991','1235','Harold IX');
insert into tags (tag_id,article_id,tag_content) values ('992','1235','Europe');

Now let's try a select that gets just the main table data ordered by BC/AD

$query = "(select article_id,year,anno_domino,description from articles where anno_domino='BC' order by year desc) union all (select article_id,year,anno_domino,description from articles where anno_domino = 'AD' order by year asc)";

Gives you:
1234 | 143 | BC | ruler XYZ invaded Rome
1237 | 64 | BC | rocknbil pillages brewery
1235 | 294 | AD | the whatchamacallit was invented by Harold IX
1236 | 312 | AD | The Ewoks Sacked Rome

As you see, ordered with BC first, years descending, AD next, years ascending, in perfect chronological order, in spite of how the're entered or the auto increment ID.

Now let's step it up, and get the tags. for a select statement, it would involve multiple lines for each of the main table records which would involve programming anyway to avoid multiple lines, so what I'd probably do here is nest it inside a for loop. (or, if there's a mySQL statement to concatenate the joined table on one line it eludes me ATM, but concat might do it.)


$output = null;
$result = mysql_query($query);
while ($row=mysql_fetch_array($result)) {
list($article_id,$year,$anno,$descr) = $row;
$tags = null;
$query = "select tag_content from tags where article_id=$article_id";
$res = mysql_query($query);
while ($row=mysql_fetch_array($res)) {
$tags .= '<' . $row['tag_content'] . '> ';
}
$output .= <p>$tags $year $anno $descr</p>";
}
//
echo $output;


The last bit is untested, but it'll work, and give you the same output as in your first post, with the exception they are wrapped in paragraph tags.

The overall assessment, thinking outside the box will pay off in the long run . . .

Mabus

8:45 pm on Jul 17, 2010 (gmt 0)

10+ Year Member



Thanks for the help Readie, I appreciate it.

Ok here's where we are. I've uploaded the script, and the text file. It does not seem to work (yet) though, so there's probably some bugs to work out.

I've uploaded the text file which contains the tags;
[dalnetdebates.com ]

and the script you provided. The only changes I made is to add the html and <php> tags so that it will be read as a web page and the path to the txt file;
[dalnetdebates.com ]

The testscript.php only shows a blank page, so I have also added the same exact page as a txt page so that you can see the source code;
[dalnetdebates.com ]

Mabus

8:47 pm on Jul 17, 2010 (gmt 0)

10+ Year Member



Hey Rocknbil, Thanks for the input.

I agree with you, that your way is much more powerful and would let me do all kinds of things with the database.

The problem really is that this is much more complicated than what I need. It's a bit like going to the corner store in the ferrari when a simple bicycle will do :)

All i'm trying to do is compile a simple text list that i can easily add to with notepad on the fly, and then have php pages on the web which will automatically grab the relevent lines.

So for example a rome.php page will only print the lines which relate to rome, and frane.php will only show the lines related to french history etc...

All that said,
If there was a simple way of doing what you suggest, using a txt file of some time (even sql or csv) that would be fantastic. But having to log into the mysql control panel and manually input each field would be greatly increasing the workload involved.

Readie

9:09 pm on Jul 17, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



My script won't be returning anything - you havn't changed the value of $input, and you havn't even assigned anything for $text_to_search.

Furthermore, what my script does when it finds your tag is create a .html file, it won't display anything on the actual page it's running on.

Also, this:

/home/username/public_html

is already generated with this:

rtrim($_SERVER['DOCUMENT_ROOT'], "/")

So currently you are saying /home/username/public_html/home/username/public_html

And finally

test.txt/

I'm creating a file with most of the characters from $input (letters, numbers, underscores, hyphens) with the suffix of .html, so the .txt above will most likely break it.

Mabus

9:40 pm on Jul 17, 2010 (gmt 0)

10+ Year Member



What I need is php code that prints lines from the main database, into a webpage when the person loads the page.

If the person loads Tag1.php for example, that page should include the php code, which will search test.txt, and then put the right lines in Tag1.php

It has to be something the user generates every time they load a page, not a page I create manually, as that would force me to create new pages everywhere, every time I updated the database (which would be a mess).

Mabus

2:32 pm on Jul 19, 2010 (gmt 0)

10+ Year Member



I've solved the problem, thanks to everyone who responded :)