ThemeShaper Forums » Thematic

[closed]

need help understanding customizing post meta and utility

(13 posts)
  • Started 3 years ago by Kyle
  • Latest reply from Andrew
  • This topic is not resolved
  1. Kyle
    Member

    I have spent countless hours today searching through these forums to find help with these issues, but I just can't find anything that answers my questions in a way I can understand. I have knowledge of HTML and CSS, but know nothing about PHP. I found many posts where people simply gave the solution code, but I would like to understand how to do this myself.

    I'm trying to customize the stuff that shows up under posts titles and at the end of posts (called meta and utility, if I've understood correctly).

    I think it would work best if I explained how I THINK it should work, and then someone can help me understand how it ACTUALLY works.

    The way I THINK it should work is that I should be able to look at the content-extensions.php Thematic file and find where meta and utility are being created. After I've found them, I imagine being able to see their component pieces. I know the code looks nothing like this, but this is the type of structure I'm imagining...

    POST META
    1. author
    2. date
    3. category
    3. edit

    POST UTILITY
    1. category
    2. comments
    3. edit

    So, to remove or change the order of these components, I'd simply delete or rearrange them (after copying everything into my child theme).

    Then, if I wanted to add a new component, there would be a master list in some FAQ somewhere of all the available "components." I could simply look at that master list of components, find the one I want, and copy/paste it into my child theme.

    It seems there should also be some way to edit the components THEMSELVES. For example, I might want to edit the "author" component so that instead of saying "By [author name]" it would read "Written by [author name]."

    I'd really appreciate it if someone could explain to me how this ACTUALLY works. To summarize (using the word "component," since I don't know what term to use), I'd like to understand...

    1. how to find "groupings of components" like my POST META and POST UTILITY in my list above;
    2. how to distinguish one component from another;
    3. how to remove, add, and rearrange components;
    4. whether there is a master list of available components;
    5. how to edit components themselves.

    I've read time and again that there are action hooks that you can "hang" actions on and that there are filters that change...something...somehow.... but I can't find anything that dumbs this down to the level I'm looking for here.

    If a really dumbed down explanation to this has already been written somewhere, please direct me to it. I generally try to search things out before writing on the forum like this, and I've found a bunch of posts and explanations of child theme development, but apparently it just isn't clicking with me.

    Many, many thanks for putting up with my utter lack of knowledge about this. I'm learning, and I REALLY appreciate the help. You guys have been great in the past.

    Posted 3 years ago #
  2. Kyle
    Member

    There doesn't seem to be much interest in answering this, which I understand. I'm sure it's a very newbie question.

    Could someone at least point me to something online that might help me understand this?

    Many thanks.

    Posted 3 years ago #
  3. middlesister
    Member

    ok I'll take a shot at an explanation. :)

    You are right in that the code for entry-meta and entry-utility can be found in content-extensions.php. Each thing you refer to as a component is created with a function and the order of the components themselves are determined in another function.

    The reason everything is broken down into separate functions is that, just like you assumed, you can change just one "component" without touching the rest. There are two ways to change these components, either through filtering or making a childtheme override function.

    An explanation of filters and how to use them can be found here http://themeshaper.com/2009/05/03/filters-wordpress-child-themes/

    For every function where you see

    if (function_exists('childtheme_override_something'))  {

    you can also use an overriding function. Make a function named childtheme_override_xxx, copy the code from the original function and edit away.

    I don't think there is a master list of every single function and filter available, it would indeed be very long. But this is a start http://themeshaper.com/thematic/guide/?page_id=12
    Generally, wherever you see the above code you can make an override function, and wherever you see

    apply_filters('filter_name', $stuff_to_filter )

    you can filter the output. And filters goes for wordpress in general too, not just for thematic. In order to find all of them, you have to go through the code.

    In short, in order to remove, add, rearrange, and edit the components you need to write some php code. Most people get by very well through simply copying and pasting functions into their child theme's functions.php. But if you want to make some heavy editing, you would have to learn a bit of php.

    Posted 3 years ago #
  4. nice start middlesister. but damn, this needs to be the first post if we ever get a wiki going- a thorough primer on the basics.

    kyle- i just didn't see your question. but now that i have, it IS a touch basic. it does get old repeating myself. but you're on the right track. you know to look in the content-extensions.php and you know NOT to make any changes there. you know about hooks and you know about filters. those "components" you are wondering about are really just functions... which either ECHO out something or RETURN something (aka NOT echoing) and middlesister just taught you about thematic's overrides.

    first make sure you have the most up-to-date version from lead dev Chris's site:
    http://developing.thematic4you.com/thematic-development-release/

    themeshaper went through some changes a while back and i thought all the old docu was removed, but it appears to be back.

    these are all good reads written by the original author himself
    http://themeshaper.com/2009/04/17/wordpress-child-theme-basics/
    http://themeshaper.com/2009/05/03/filters-wordpress-child-themes/
    http://themeshaper.com/2009/05/25/action-hooks-wordpress-child-themes/

    you can look at:
    http://www.bluemandala.com/thematic/thematic-structure.html
    or
    http://visualizing.thematic4you.com

    to see some of the the functions and hook names. you can also see the function names and where they are added to in the library/extensions folder

    now my primer on adding and removing functions to/from hooks

    it always works the same when you are adding and moving stuff. you add FUNCTIONS to HOOKS. think of hooks like parking spots. some are empty, some have cars on them. you can move the cars around, etc.

    function function_you_want_to_add(){
        echo "I heart bacon!";
    }
    add_action('destination_hook','function_you_want_to_add',$priority# );

    removing stuff works a bit differently:

    function remove_stuff(){
        remove_action('hook_location','function_you_want_to_remove',$priority# );
    }
    add_action('init','remove_stuff');

    init is just a default wordpress hook. in fact, it is the FIRST one that runs when WP starts whirring.

    now my primer on using filters

    it took me a long time to understand filters. think of filters like this... they are still parked in the same parking spot, but something about the car is different. filters change something w/o moving it.

    you can filter anything that says apply_filters('this_is_the_filter_name', $somevariable);

    filters take something IN and spit something OUT. send a blue car into the function and it might come out red.

    function sample_filter_function($input_from_original){
      $send_output_to_filter = $input_from_original . " Add some bacon!";
      return $send_output_to_filter;
    }
    add_filter('this_is_the_filter_name','sample_filter_function',$priority#);

    whatever content WAS going to be printed will now have " Add some bacon!" tacked on to the end, b/c well.. who couldn't use more bacon?

    lastly, the $priority# stands for priority number. it is like a traffic cop in the parking lot. or maybe just an orange cone. if more than 1 function wants to be on a particular hook the priority decides which goes first same as if 2 cars want to park in the same spot (sorry, had to beat this metaphor to death). the higher the number the later it gets run. this can be important, but is not always necessary.

    props to @kwight for starting the parking metaphor. apparently my ball-pit metaphor didn't make any sense b/c no one knew what a ball-pit was.

    hope that helps.

    Posted 3 years ago #
  5. drewmcmanus
    Member

    thank you all VERY much for this. I too have been very frustrated over the lack of documentation and perhaps more importantly relevant examples, for the proper way to edit or filer out metadata in posts. For example, having a copy-and-paste reference for going about removing the "Published" bit from the entry meta is driving me insane.

    If anyone has some practice examples they can post for the functions within the entry-meta and entry-utility sections, I'd be enormously grateful!

    P.S. I've been over the Using Filter Hooks in WordPress Child Themes pages and I find them entirely confusing as they don't include any real examples from the sections I'm trying to work with.

    Posted 2 years ago #
  6. 'they don't include any real examples from the sections I'm trying to work with'

    i think that it's unnecessary, b/c filtering the site title is the same as filtering the post meta is the same as filtering the post footer. that's what i was hoping to explain in my post.... a generic 'how to filter', b/c it is the process of filtering that stays the same, just the different filters you can apply it to.

    i'm not saying that the 'Using Filters' article is the easiest, b/c I know I personally took a long while to sort of filters too. but if you understand my above metaphor you can filter anything, anywhere.... wordpress core, parent theme, plugin, etc.

    Posted 2 years ago #
  7. drewmcmanus
    Member

    unfortunately, I don't understand the above tut. Anyone willing to make $50 to give me a quick phone tutorial?

    Posted 2 years ago #
  8. i can help via email if you're interested. my email is just my username at gmail

    Posted 2 years ago #
  9. Kyle
    Member

    Sorry it has taken me so long to respond, but I want to thank middlesister and helgatheviking. I've spent a good amount of time in the past couple days reading about this kind of stuff and learning some PHP basics, and I think I understand most of what both of you are saying. Now that I understand the "basic concepts," I need help understanding the "how exactly do I actually do this" side of things. Here's an example, using the same meta and utility stuff I talked about at the beginning.

    I want to

    • remove "By [username]"
    • remove the "|" between the username and date stuff
    • remove "Published:" before the date
    • change the date format to "[day of the week], [month] [date], [year]
    • move "Posted in [category]" to immediately after the date

    There are more things I want to do, but I think those provide examples of a few different types.

    I opened up content-extensions.php, as suggested. Then, with my new understanding of action hooks and filters ready to go... I realized that I'm still completely lost.

    1. How do I know where to look in content-extensions.php to find the stuff I want to hook/filter?
    2. If I hadn't known to look in content-extensions.php, how would I have discovered that?
    3. Once I find that stuff, could someone give me examples of how to do some of the above things I'm trying to do?

    I'm perfectly willing to read documentation online or buy a book from somewhere, but I can't find anything that teaches these kinds of things. If anyone has any resources suggestions, I'd much appreciate it.

    Again, many thanks for help.

    Posted 2 years ago #
  10. 1. i'm sure it is intimidating, but you have to read the functions. what is creating what? they all say things like return $posttitle or $postmeta = "something".

    do you have notepad++ or some other decent text editor? if not, get it:
    http://notepad-plus.sourceforge.net

    it makes your life a lot easier. you can search through the text in an open file OR in closed files. for instance, i quickly searched for the term 'By' in content-extensions.php and it brings me to exactly the function that creates the By Author link. thematic_postmeta_authorlink(). within said function i see the filter thematic_post_meta_authorlink, which I could use to remove the By [username] from the meta (or use the override)

    or, b/c that function is returning a value that tells me it is being used/called somewhere else. searching for thematic_postmeta_authorlink brings me to
    the thematic_postheader_postmeta() function that is calling it. this is probably the most effective place for us to be since all your changes are to the post meta. you could've gotten here more directly by searching by a different HTML class.... the whole post meta is in a div with a class of "entry-meta"

    now you are at the thematic_postheader_postmeta() function and you know you can filter it too b/c as i said in my above post (please re-read the part on filters!) you know you can filter the value b/c it says APPLY_FILTERS and you can tell the filter's name is thematic_postheader_postmeta. you could trace this further to thematic_postheader, but i'll save you the trouble and let you know you are in the right place.

    in my previous post i put up a generic filter function. one that doesn't work, but one that you can fill in the blanks for any situation. one that i hoped would explain what the hell is going on with a filter. THIS example will do something.

    function kia_postheader_postmeta($postmeta){
      $postmeta = "BACON!";
      return $postmeta;
    }
    add_filter('thematic_postheader_postmeta','kia_postheader_postmeta');

    put it in your functions.php and all your post meta will be replaced with BACON! you have sent a variable back to the APPLY_FILTERS and it is using your value instead of what was already defined.

    as much as bacon is delicious you probably don't want it displaying on every post. but this is where you can define exactly what you DO want to display. you can use anything that is RETURNED. you can use string text (like 'bacon'), string html (like '<div id="bacon">bacon</div>') or conveniently any other function that RETURNS a value.

    function kia_postheader_postmeta($content){
       $postmeta = '<div class="entry-meta">';
       //$postmeta .= thematic_postmeta_authorlink(); //delete this
       //$postmeta .= '<span class="meta-sep meta-sep-entry-date"> | </span>'; //delete this
        $postmeta .= thematic_postmeta_entrydate();
        $postmeta .= '<span class="meta-sep meta-sep-entry-date"> | </span>'; //added this
    
        $postmeta .= thematic_postfooter_postcategory(); //added this. found that the categories list at the bottom is created by this function using a search for the class 'cat-links'
    
        $postmeta .= thematic_postmeta_editlink();
    
        $postmeta .= "</div><!-- .entry-meta -->\n";
    
        return $postmeta;
    }
    add_filter('thematic_postheader_postmeta','kia_postheader_postmeta');

    sometimes a filter is the best solution, but it might have been easier to use the built-in override in this case. you would have seen it in the content-extensions.php. says if childtheme_override_postheader_postmeta exists then use THAT instead. when i use an override, i will commonly copy over the contents of the original function and then make my changes.

    function childtheme_override_postheader_postmeta(){
    $postmeta = '<div class="entry-meta">';
    	    //$postmeta .= thematic_postmeta_authorlink(); //delete this
    	    //$postmeta .= '<span class="meta-sep meta-sep-entry-date"> | </span>'; //delete this
    	    $postmeta .= thematic_postmeta_entrydate();
    
                $postmeta .= '<span class="meta-sep meta-sep-entry-date"> | </span>'; //added this
    
                $postmeta .= thematic_postfooter_postcategory(); //added this. found that the categories list at the bottom is created by this function using a search for the class 'cat-links'
    
    	    $postmeta .= thematic_postmeta_editlink();
    
    	    $postmeta .= "</div><!-- .entry-meta -->\n";
    
    	    return $postmeta;
    
    }

    you'll note there is no need to add_filter or add_action when using the override.

    2. if you hadn't known about content-extensions... well i have to wonder that if you were looking for something why wouldn't you look around in all of the thematic files? to look more expeditiously you could use notepad++ to search in files. i know where almost everything is now, but when i am using a new theme or looking for something in WP core, then i tend to search by class name. this is b/c alot of the content is variable and i don't necessarily know the variable name to search for, but the html classes change rarely. if you look at the site w/ firebug you would see the author link is surrounded by a span with the "meta-prep-author" class. you could search for that in the whole thematic folder and it would bring you to the exact function in content-extensions.php.

    3. see above postmeta example in part 1.

    **************

    "but I can't find anything that teaches these kinds of things"

    i respectfully call shenanigans. for one, you are on a thread where i've posted links to sites that explain these things

    http://themeshaper.com/2009/05/03/filters-wordpress-child-themes/

    has both bacon-flavored generics and actual thematic examples. i'm sure you could also google wordpress filters or thematic filters to get more similar sites. additionally, i have written my own tutorial on the subject in this very thread.

    SO, what i'd like from you is to know exactly where that information is unclear. i am not trying to be an ass, but 1. it gets tiresome explaining the same concept over and over b/c 2. everyone is getting hung up on the same thing. this tells me that either people are lazy and can't/won't read what is available, hoping that someone on a forum will do the work for free instead of hiring a developer. OR it tells me that what is available, while it makes perfect sense to those of us in the know, is still confusing from the newbie's perspective.

    therefore i am asking for your help w/ the second part. your questions were a decent start and a step above the common cop-out "i don't understand!", even though i think at least most of 1 and 3 were answered in this thread and in the links provided in this thread. i don't want to sound like an ass, but i want to know WHY it is confusing? what specifically is unclear? what do you need to understand that was not already provided? what did you try and not have work? i'm serious.

    this will help me improve the structure and content of my tutorials/explanations so that they make sense to the newbies they are targeted at.

    cheers.

    Posted 2 years ago #
  11. Kyle
    Member

    First of all, thank you again.

    Secondly, I'm sorry for frustrating you. Thank you for sharing that frustration with me rather than not responding at all.

    Regarding finding things, either within a file or when trying to find the right file, I knew that I could "manually" look through every Thematic file. I guess what I was getting at, but didn't know how to ask, was what are the differences between PHP files in the "root" Thematic folder and the PHP files in the library>extensions folder? As I was looking through them and trying to answer that question, I thought I had come to the understanding that the PHP files in the "root" Thematic folder "stand on their own" (can't think of a better way to say that), while the PHP files in the library>extensions folder get called upon by multiple PHP files in the "root." However, as I looked more, I noticed files like header-extensions.php, which looks to me like something that would only really be called upon by header.php (though correct me if I'm wrong). This makes me wonder why the PHP in header-extensions.php isn't just in header.php. I think that understanding this concept would help me know where to begin looking.

    Your tips on searching closed files and searching by HTML class were helpful to me. Thank you.

    Reading through the following portion of you most-recent post, this is what is going through my mind as a beginner.

    • I understand how you searched for "by", and found thematic_postmeta_authorlink().
    • Although I know almost no PHP, I understand that because thematic_postmeta_authorlink() was not echo'ing anything, but only return'ing, it let you know that it must be being used/called somewhere else.
    • I understand, then, why you searched for "thematic_postmeta_authorlink()" and found thematic_postheader_postmeta().
    • I understand that both thematic_postmeta_authorlink() and thematic_postheader_postmeta() could be filtered because they both include "apply_filters".

    Then you go into your kia_postheader_postmeta($postmeta) example.

    • I understand that functions ("action functions"?) can be hung on hooks in the form (from your previous post) "add_action('destination_hook','function_you_want_to_add',$priority# )".
    • I don't understand the "hang on a hook" equivalent for filters. According to your previous post, the form to follow is "add_filter('this_is_the_filter_name','sample_filter_function',$priority#)". In your kia_postheader_postmeta($postmeta) example, you replace "this_is_the_filter_name" with "thematic_postheader_postmeta". I think I'm confused about how "thematic_postheader_postmeta" can be both the name of the PHP function that helps "build" the post meta stuff and the name of a filter. Are the PHP function and the filter of this same name two different "things" or one and the same? If they're two different things, I guess I just need to be told that filters and functions can have identical names without causing problems. If they're one and the same, it makes more sense for me to call "this_is_the_filter_name" in your example "function_you_want_to_filter".
    • Because I don't know much PHP, I'm confused about why you need to give both "$postmeta" in your function parentheses, "kia_postheader_postmeta($postmeta)" and give "thematic_postheader_postmeta" in place of "this_is_the_filter_name". I know you said "you have sent a variable back to the APPLY_FILTERS and it is using your value instead of what was already defined," but I'm wondering why it wouldn't work to only "re-assign" a value to the "$postmeta" variable, then when WordPress got to the "thematic_postheader_postmeta" it would know to use the new variable value. Is this because functions.php is "read" later and this "add_filter" thing tells WP to go back and "redo" the other function with this new variable value? I apologize if this is an especially stupid question. I'm sure it is.

    Your next example code includes the variable "$content". I don't understand where that came from. I tried following you advice and searching through the content-extensions.php file just now for "$content," but didn't find anything that seemed to relate to the post meta kind of things we're working with here. Again, sorry if this is something everyone else "just knows."

    Otherwise, I understand the rest of that example code, including how you searched for and found the function for the category.

    The difference between filtering and using an override makes sense to me. Thank you.

    Regarding being able to find help:

    • I appreciated your links to other sites and had read those back when you posted them. I have read that ThemeShaper blog post on filter hooks multiple times, and it did help me in some ways, but obviously still didn't answer the questions I'm asking here.
    • You also say, "you could also google wordpress filters or thematic filters to get more similar sites." I've spend many hours doing this, and maybe I'm just not searching for the right things, but I honestly can't find anyone who's dumbed it down to the level that I need (the level of the questions in this post, that is).
    • You said, "i have written my own tutorial on the subject in this very thread." Again, I very much appreciate that you did and I have read it multiple times, very closely, but as you can see, still had questions.

    I could write more about the things I don't understand (and haven't been able to find simplified explanations for), but I hope this has answered your request for "where that information is unclear." I can certainly understand that explaining these types of things would get very frustrating for you, and I'm thankful you've stuck with me on this.

    You said that since everyone is getting hung up on the same thing, it means that either "people are lazy and can't/won't read what is available, hoping that someone on a forum will do the work for free instead of hiring a developer" or that "what is available, while it makes perfect sense to those of us in the know, is still confusing from the newbie's perspective." I obviously can't speak for every WP/Thematic newbie, but I know that the latter is true for myself. As I wrote, I'm willing to read anything, be it a book, forum post, website, or watch a video somewhere, but I can't for the life of me find anything that's written for someone like myself who doesn't know any PHP and is new to the "inner workings" of WP and is trying to understand how Thematic works. I'm a college student still on my Christmas break and have set aside a handful of days in which I've been trying to learn about this stuff. When I finally get all of this figured out, I'd be happy to collaborate with someone or create on my own some kind of documentation for WP, Thematic, and PHP newbies who want to be able to not just copy-paste their way to customized themes (or get people on forums to do the work for them, as you say), but who want to actually understand why code examples they find work and how to do these kinds of things themselves.

    Having almost given up on finding online help at this ultimate newbie level, I have started reading both the "Smashing WordPress" and "Build Your Own Wicked WordPress Themes" (which actually uses Thematic) books. I haven't finished either yet, but so far neither has addressed the types of questions I'm asking here. They've been largely above my head (or doing things in ways that don't line up with how online instructions I've found have said they're supposed to be done).

    I was wondering if I'd be better off just learning PHP before I try to go any further. I spent about 10 hours watching and reading PHP tutorials, but I found that what they were teaching wasn't necessarily what I needed to know to customize WP/Thematic. One thing that might be useful is a "this is the PHP you should know to work on WordPress stuff" tutorial.

    Thank you again, helgatheviking.

    I apologize for the length.

    Posted 2 years ago #
  12. don't apologize for the length, it is very much was i was hoping to receive when i asked you my questions. you just happened to be the unlucky "victim" as i've been wondering this for a while. i appreciate how much effort you're putting in and your desire to actually learn. that makes me happy b/c i like helping people to learn. i'm a freelance developer myself, so i don't like doing people's work for them for free.... which you do see on the webs esp in regards to wordpress.

    filters took me a long time to learn, so i am aware that they don't make the most sense. the override function is much more intuitive (which didn't exist when i started with thematic). which is why i have put effort into trying to break filters down for newbies. with your help maybe we can break it down further. the fact that you're coming around in less than the year it took me to fully understand them says something about the explanations must be working. they're hard. it is foolish to think you are going to grasp them in 30 seconds.

    first filters and functions CAN share the same name. this was a hang up for me for a while actually. b/c i thought that to filter the output of a function you targeted your add_filter at the function name. this mostly worked as thematic tries to match the filter name to the function name as much as possible. but i ran into trouble with filtering the thematic_post which is the filter inside the thematic_content() function. got some help from Ninja Gene (em_hr) and my understanding of filters expanded. that's why i try to emphasize that filters exist only where it says APPLY_FILTERS. the name of the filter is whatever is defined inside that APPLY_FILTERS function.

    next, without going line-by-line through your post i think you are struggling what is called variable scope in PHP. i'm not really qualified to explain it. maybe this will help?

    http://www.elated.com/articles/php-variable-scope-all-you-need-to-know/

    most of the variables in thematic functions are what is called local scope. that means they only exist inside the function they are created in. scope is important, b/c what if you have thousands of functions between WP, your theme and all your plugins. what if function ABC() had a $content variable and so did function XYZ? whose value of $content would WP use? you can make a function have what is called global scope and be available to any function to use. you'd do this by

    global $variablename;

    again you'd want to make that sort of unique to reduce the chance of someone else monkeying with it.

    wordpress and thematic both use some global variables. for instance, $post is a WP global. as is $wp_query. if you did

    global $post;
    $post = "bacon"

    inside one of your functions (something that got called), you'd probably break your site b/c WP needs that variable.

    that is why, in my above example, i can create $content. looking at my function. inside the function of original thematic_postheader_postmeta it has a different name. but it is just a variable name. so when that value gets passed to my function as a argument

    http://php.net/manual/en/functions.arguments.php

    whatever i name my new variable (as the function argument) is what i will use to refer to that variable INSIDE my new function. hence the $postmeta from the content-extensions.php is now $content, but it is only $content inside my function. in content-extensions.php the variable could have been $xyz or $bacon or anything... same with inside my function. giving it a relevant name helps you understand what it is when you look back at it later. nothing is worse than deciphering code that is written w/ meaningless variable names like $x1 or $b.

    i think i need to make a diagram for apply_filters.

    lastly, b/c i have to go: all this code COULD well be hard-coded into header.php or index.php, etc. and lots of themes do it this way. it is probably easier to LEARN WP that way. those themes are fine, but they don't work as frameworks. frameworks are great, but they do add an extra layer of complexity to your learning curve.

    Posted 2 years ago #
  13. Thanks to the post I just managed my first Filter on my own! Man that took waaay longer than it should. Thank goodness for childtheme overrides, but now I can do things a little more efficiently.

    Also the link to PHP articles on Variable scope and starting with functions are super handy. I can definitely identify with Kyle, and a designer, who is slowly getting into the developer role, it's hard to teach yourself all the basics at the proper speed without getting in over your head quickly. Wordpress makes it really easy to make websites, but to understand and be able to modify how the nuts and bolts work has been a wonderful challenging ride so far.

    Thanks Helga!

    Posted 2 years ago #

RSS feed for this topic

Topic Closed

This topic has been closed to new replies.