Jump to content

Categorisation vs. Relation


BFD Calendar
 Share

Recommended Posts

Is it possible in ProcessWire to 'construct' a text output from fields on different pages in different categories that are linked by a relational ID as in a relational database?

Sample of text output:

495 YEARS AGO - on Sunday 29 September 1518
(+)
Artist Tintoretto originally Jacopo Comin aka Il Furioso, is born in Venice, Italy.

-------------------------------------------------------------------------------------------------

Where "495 years ago" is calculated from the date field in the 'event' page (the one that gathers information from other 'related' pages), "Artist", "Tintoretto", "Jacopo Comin" and "Il Furioso" are fields (occupation, lastname, original, alias,....) in a 'name' page, and "Venice" and "Italy" are fields in a 'location' page. The 'name' and 'location' pages would all have a unique ID linked to the 'event' page (with a unique ID as well) to get the related fields.

This would also allow the page "Tintoretto" to list all 'event' pages that are related to Tintoretto and the page "Venice, Italy" to list all the events that happened in Venice.

The data is now stored in a Filemaker database and I'm looking for a convenient solution to transfer it to a website. In the meantime a html-export version can be found at http://www.birthfactdeathcalendar.net. There are over 10000 events and 4000 names.

The 'Scyscrapers' sample website comes close to what I'm after but when digging in deeper I guess I need some extra skills in defining what goes where (categorisation) and how to bring it together (relation).

Any help or guidance is mostly welcomed.

Link to comment
Share on other sites

Yes, it is possible of course. It would look more or less like this:

foreach($pages->find("template=person") as $p){
    $timeAgo = date("Y") - $p->year;
    echo "<p><span>{$timeAgo}</span> YEARS AGO - on {$p->weekday} {$p->day} {$p->month} {$p->year}</p>";
    echo "<p>(+) {$p->occupation} {$p->lastname} originally {$p->original} aka {$p->alias}, is born in {$p->city}, {$p->country}.</p>";
}
 

Dealing with dates in your case won't be easy because you can't use unix timestamps (starts in 1970). That's why I chose to have all the details from the date in different fields. There might be better ways to deal with this of course.

You can also import the database by exporting the database to csv and importing it to PW. This module is great for that http://modules.processwire.com/modules/import-pages-csv/. You will have to plan carefully and build all the structure in PW before.

  • Like 2
Link to comment
Share on other sites

The dates are not my biggest concern, I can easily export them from Filemaker as three fields (dd, mm and yyyy) and use php to calculate the 'years ago'.

Exporting to csv and importing into ProcessWire also works like a charm, I already tested with the 4000 names.

I understand that this needs careful planning. It's a bit confusing to decide what should be main categories with parent and child pages. I have the impression you can go on in dividing data almost endless. A major doubt right now is to decide if 'events' should be categorised by date (parent=month -> child=1,2,3,.... -> child=event1959a, event1959b, event1969a, event1983a,....) or by event (parent=event -> child=birth, fact, death -> child=event). In the last case it's possible to keep categorising forever. For instance deaths can be split up in say cause, suicide and murder. Then again cause can be split up in heart attack, stroke,.... But in the end they should all show up in pages listing events resulting from user searches like "what happened on my birthday?", "which musicians were born in my hometown?" or "who was murdered by an axe in Belgium?".

Link to comment
Share on other sites

In this case I have the feeling you don't have to categorize a lot because events are very independent and dates are automatically categorized already (because there is a sequence). I think you should be more concerned about things like (which musicians were born in my hometown?). You can have those fields as page fields, and create the pages for the existing countries and cites in those countries, to link to. 

Kongondo wrote a great guide about categorization http://processwire.com/talk/topic/3579-tutorial-approaches-to-categorising-site-content/

Link to comment
Share on other sites

It sounds like you might be getting hung up on how to structure each entry - my advice would always be to treat people and categories separately where you need to place a person in more than one category.

For example, all of your people would go under /people/ with a template called "person" and each category stored in a tree like /categories/deaths/, /categories/deaths/suicide/, /categories/deaths/murders/ with  template called "category". That way you could create a Page field called "categories" (Page List Multi Select like this would be favourite: http://processwire.com/videos/page-fieldtype/ ) and add it to the "person" template so that you can tag multiple categories against the same person.

This way, you can do some searches like this:

$people = $pages->find('template=person, category=suicide|poison');

That will return a PageArray of all people who match categories of suicide or poison. You could also do some weighting of results so that the more categories they match the higher they come in the results, but I think your biggest hurdle will be turning your human-readable search string into something useful.

Once you've done that though, you're simply matching the keywords against categories in ProcessWire and the rest is relatively easy :)

Something like this as a quick example:

<?php
foreach ($people as $person) {
    echo "<h1>$person->title</h1>"; // Their name
    echo "Died of: ";
    echo "<ul>";
    foreach ($person->categories->find('parent.name=deaths') as $death) { // Searching under a parent page name of deaths within this person's categories will return how they died - quite lengthy for some historical figures!
        echo "<li>$death->title</li>";
    }
  echo "</ul>";
}

Of course, you could have a whole separate categorisation system for deaths rather than lumping things together under categories like this, but since you're likely to have a great many categories and everything you would search for in this system is a means of categorisation I thought I'd do the example above.

  • Like 1
Link to comment
Share on other sites

Thinking about how you would use a person#s free-text search string (assuming you wanted to) like this:

Who was born in 1776?

You would be wanting to look out for words like "born" first, and then look for a 4 digit number. More complex is this:

Who was born or died in 1776?

as you would then have to look for both "born" and "died" and then the year, but that's not too difficult. Worse still is this nightmarish example:

My birthday is 1st October 1981. Who was born or died from poison on that day?

Nobody is likely to type that in, but your key words there would be birthday, born, died and posion with a date being harder to pull out depending on locality of the person searching (for example, I could have typed "October 1 1981" instead, so you would need some sort of regex to catch the most common of those if you wanted to). Once you have your result from that query though, you could weight (or just categories) the results by people who were born or died on that day, people that have birthdays on that day and people that were poisoned on that day.

And now I'm getting a headache thinking about it all :D But I definitely think that if you allow search strings like this then matching against key search phrases (born, birth, birthday, died, dead, death, murdered etc) and then looking for some form of date is the way to go to work out what the user actually wants.

I think you might give up at the point someone types "Who was born or died between October 1 1990 and 22 November 1990 and who was poisoned on 3 February 1700..." etc etc - more than one date might get tricky, but it feels like the best way to approach it is to assume people won't type in anything ridiculous as those who do will be in the minority (hopefully!) :)

At any rate, I think you're going to have some fun (and headaches) with your search algorithm!

  • Like 1
Link to comment
Share on other sites

On another note, maybe you should consider removing the background (or making it much lighter). I really have trouble to read the texts over it.

The old cards on the right side are beautiful though :)

Link to comment
Share on other sites

The background is a 1980s photocopy enlargement of a computer data file on film. I never knew what information was held there.... Readability could be a bit of a problem indeed. The old Calendars were just typed with a typewriter from written information in a notebook, pre-computer age. Later on I switched to a Commodore 64 computer with cassettes to store data, then I moved to a FoxPro database and finally to a Filemaker database.

The old Calendars are collector's items now.

http://www.en.zvab.com/advancedSearch.do?title=Birth+Fact+Death+Calendar&author=Devos

Link to comment
Share on other sites

Thank you for your insights all. I'll let them sink in and start a little sample site to see where it goes.

Regarding searches, I'd be happy if I could have pre-defined search criteria like the Skyscrapers site for a start, before attempting to serve the most complex demands.

I'd definitely want a separate category for places because they do look great on a Google Map. They could very well function as a 'places to visit' when you're on holiday.

Compared to the 1980s it's now also much easier to find out what happened 'exactly' where.

So basically there would be three main categories to start with: events, people, places? Places would be the easiest because there's always only one place in one city in one state in one country. People a bit more complex because they can have more than one 'profession'. And events being the most complex, not just to categorise but also to retrieve linked information from people (with more than one possible) as well as places.

Link to comment
Share on other sites

I think the people are your starting point in this case, as each one that's added would relate to places and events and populate those sections. The trouble would be keeping track of which places and events have already been added and linking to them accordingly,  but I suspect that you've got the perseverance to pull it off since it seems you've already collated this data yourself over a number of years :)

Link to comment
Share on other sites

In my Filemaker setup I have only two databases, one for events and one for people. When I check a record for someone in the people database I can see all related events in a 'portal'. That makes it very easy to check if some event was added or not. Most input fields are popup menus or lists that also make it convenient to see if something was added or not.

Until now every event and person has a unique 'Filemaker' ID that I can import into the ProcessWire pages. That can keep everything together for a start. From here on I just have to find out a new automatically adding ID or a search for the last entries and I'm done.

For the website I would add a 'places' category because I often end up with clicking "New York", "New York", "USA" for a lot of events.

And yes, I do enjoy finding new events to add once in a while. Now I'm the only one enjoying searches and weird coincidences in my Filemaker database, but I'd like to share that joy to others as well.

Link to comment
Share on other sites

For the places you can create a page "places" with countries inside and cities inside them.

+places

    -Angola (template=country)

    -Brazil

    -Mozambique

   +Portugal

        -Aveiro (template=city)

        -Beja

        -Lisbon

        -Porto

When importing from the database you can check for each person entry if the country and the city exists, and create them only if not, and then link this person to the city. You can also link to the country but it's not needed because you can get it like this:

$country = $page->city->parent()->title.
Link to comment
Share on other sites

Hm, a person is generally connected to several places. Few people die in the same place as where they were born. 'Places' should definitely be linked to 'events'.

Regarding to the listing, there can also be several places in one city. The good thing with MapMarker is that you can really pinpoint to exact locations. So I have fields for country and city, but also state, district, street and name, where name could be the name of a hotel, hospital, school or whatever. I'm also an avid visitor of 'places of interest' myself so I want the location of events to be as precise as possible. On rare occasions the exact same location appears twice in history 'by chance'. Mama Cass of the band The Mamas & The Papas died of a heart attack in 1974, in the same apartment where Keith Moon of The Who overdosed in 1978.

When importing from the database I still have to check and update coordinates anyway. Since a lot of my information dates from pre-Google Maps era it's quite fun to update certain places with 'new' technologies.

Link to comment
Share on other sites

  • 3 weeks later...

Getting back to my places problem above.

I have a 'places' template with 'name', 'street', 'district', 'city', 'state', 'country' and Mapmarker fields. Cities, states and countries are select fields.

How can I get these fields into an 'event' page by referencing them to either the title field or a unique ID field? Something like having the title or ID from the 'places' page as a select list and pull the other fields from that page into the 'event' template, including the Mapmarker map.

Link to comment
Share on other sites

I solved it like this:

        <?php
        $namepage = $pages->get("template=bfd_people, id=$page->bfd_events_people_id");
        $occupation = ucfirst($namepage->bfd_people_occupation->title);
        if($namepage->bfd_people_original) {
		$originally = ", originally " . $namepage->bfd_people_original;
		};
		if($namepage->bfd_people_alias) {
		$alias = " aka " . $namepage->bfd_people_alias;
		};
        echo "<b><a href='{$namepage->url}'>{$occupation} {$namepage->bfd_people_name_first} {$namepage->bfd_people_name_middle} {$namepage->bfd_people_name_last}{$originally}{$alias} </a></b>";
       ?>
  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...