Jump to content

One page website template setup?


photoman355
 Share

Recommended Posts

Hi,

Just started using PW and really love it.  I've started to create my own template and was hoping I could get some advice on how best to go about my project.

I've created a one page website which uses HTML, CSS and Javascript and want to convert this over for use with PW.  The concept is fairly straightforward, it's a series of module blocks of HTML which I can move to alter my layout.  Here's an example of the structure:

Header
    Page1
        Module1
        Module2
        Module3
    Page2
        Module1
        Module2
        Module3
Footer

Page 1 and 2 are essentially <div> containers and each module is also contained in it's own <div>.  My understanding of PW is the code for each module I've created would get wrapped into various custom Template Files which could then be positioned as required within the page Template.  Is this correct?  

I plan to use this layout for multiple sites so I also wanted to know if it was possible to create the module blocks in such a way that they could easily be installed/ported across to another site?

Any advice or links to creating this setup would be greatly appreciated.

Link to comment
Share on other sites

Well, at the simplest you could just set up several fields in ProcessWire (one for each module) and then just add them to your template.

So amusing you have a separate head and foot, your basic-page (or whatever template you want to create) could be as simple as:

<?php 

include("./head.inc");

echo "<div class='myfirstfdiv'>{$page->modulefield1}</div>";

echo "<div class='myseconddiv'>{$page->modulefield12}</div>";

echo "<div class='mythirddiv'>{$page->modulefield3}</div>";

include("./foot.inc");

?>
 

That would display the contents of the fields. How you wrap it up is up to you and you would do that in your template.

It depends if that would be the end of it, or would you want to get more versatility - have more block positions on a page, be able to chose different content from a library of content and so on.

If you haven't done it already, have ago at this tutorial to get you going:
 

http://wiki.processwire.com/index.php/Basic_Website_Tutorial

Joss

Link to comment
Share on other sites

Many thanks for getting back to me so quickly Joss.  Juging by your reply it looks like I'll be able to create what I'm after which is fantastic.  

I definitely want to alter block positions and make the setup more versatile so will give you a shout once I've read through the tutorial you sent over. 
Link to comment
Share on other sites

  • 2 weeks later...

It took me a while but I now have a working example of something that resembles the setup above.  I didn't quite get the concept initially that in processwire a page doesn't actually have to be a page, it can just be a data container for my code.  Once I got that I managed to put the site together, see code below.  Hopefully this will give others a few pointers too.  I'm not convinced it's necessarily the best interpretation so it would be great to get advice on this.  

My homepage code is like this:

<?php include("./header.inc"); 

/**
 * Homepage template
 *
 */

$items = $page->children; 
foreach($items as $item) echo $item->render(); 

include("./footer.inc"); ?>

As this is a one page website and pages aren't actually physical pages, this allows me to pull in data from child pages of my homepage.  My page template looks like this:

    <div class="page">     
        <div class="header" id="<?=$page->title?>">
        <a name="<?=$page->title?>"></a>
        
            <!-- Any content I want in here -->
        
        <?php foreach($page->children as $child) echo $child->render(); ?>
    
    </div>
    </div>

I wanted to create dynamic navigation.  In one page websites the navigation is setup with ID's so the <?=$page->title?> reference allows me to set up whatever page title I want in the backend and have it pulled in as the target for my navigation.  Setting up the navigation was fairly straightforward. I based it on Ryan's tutorial here , the code is very similar, I just added href="# and removed the url reference.


<ul class="nav">
     <?php
        $root = $pages->get("/");
        $children = $root->children();
        foreach($children as $child) {
            echo "<li><a href='#{$child->title}'>{$child->title}</a></li>";
        }
        ?>
</ul>

I did run into a small problem as I'm using jquery's scrollTo plugin on the links.  My original code looks like this and the jquery breaks most likely due to conflict with the php.  I originally had this in my footer scripts and changed it over, can't quite remember why off the top of my head but there was a good reason from memory.  I also need to get the "active" class working.  Any idea how to rewrite/handle this?



<ul class="nav">
  <li class="active"><a href="#page1" onClick="$.scrollTo( '#page1', 800 );">Home</a></li>
  <li><a href="#page2" onClick="$.scrollTo( '#page2', 800 );">Page 2</a></li>
  <li><a href="#page3" onClick="$.scrollTo( '#page3', 800 );">Page 3</a></li>
</ul>

Moving back to my page template I have the line 

<?php foreach($page->children as $child) echo $child->render(); ?>

This allows me to pull my module code blocks into any page just by assigning a module template to the child page.  The structure is the same as my first post but here's where it gets slightly complicated.  My modules most of the time span the full width of the page however I also have a few cases where a module just becomes a simple div container and smaller sized code blocks/widgets are positioned within the module itself.  It looks something like this:

Header
    Page1
        Module1
              Submodule 1 (1/3rd width of container)
              Submodule 2 (2/3rd width of container)
        Module2
    Page2
Footer
 
The above is just an example but I could have 3 submodules within a module block.  As they can be in any combination and position it wouldn't make sense to write all the possible combinations in a module block.  At the minute to solve this I have a module container with the same php line that's in my page template to pull any submodule content into the module block.  
 
While this works I'm not convinced this is the best solution because from the users point of view they have to navigate through the page hierarchy  to edit specific blocks rather than all the blocks relative to a page being on that page in the backend.  I know I could call in the module templates to my page template with php but that's not very friendly from an admin point of view because it requires editing the main page template each time the module structure needs changed.  What's really needed is a way of hiding the module/submodule child pages from the user and pulling all the blocks into their parent page for editing in the backend.  
 
Any advice would be greatly appreciated.
  • Like 2
Link to comment
Share on other sites

Seems like a good approach to me.

<div class="header" id="<?=$page->title?>">
<a name="<?=$page->title?>"></a>

You should use $page->name for the IDs instead of $page->title, because it will strip the spaces and any character that is not allowed on IDs. Maybe this is even the reason why your jQuery scrolling is broken.

from the users point of view they have to navigate through the page hierarchy  to edit specific blocks rather than all the blocks relative to a page being on that page in the backend.

Doesn't seem bad to me, but you may prefer repeaters for this.

  • Like 1
Link to comment
Share on other sites

Thanks diogo.  I changed the code over to $page->name and I'm still getting the same error.  What seems to be happening is the "$" call for jquery is messing with the php as it's inside the script.

echo "<li><a href='#{$child->name}' onClick="$.scrollTo( '#{$child->name}', 800 );">{$child->title}</a></li>";

My guess on how to solve this would be to take out the jquery from the link and call scrollTo on $child->name from my footer scripts.  I have no idea whether taking to php via jquery is possible or not.  Any ideas?  If it is possible do you know how would I go about implementing something like that?

On the site setup I'm glad you think I'm on the right track.  From an admin point of view there are no issues at all, I'm just thinking how to make editing as easy and logical as possible for clients.  I'll investigate the repeater fields.  

It would be handy if there was a way to create admin templates to pull in the admin fields of multiple templates in much the same way as can be done on the front end.  

Link to comment
Share on other sites

The problem is the quotation marks. You are interrupting the string by using double quotes inside of double quotes.

Try this:

echo "<li><a href='#{$child->name}' onClick='$.scrollTo( '#{$child->name}', 800 );'>{$child->title}</a></li>";

It even has a better color, hein? ;)

edit: the above code is wrong. Check horst's post below.

Link to comment
Share on other sites

The problem is the quotation marks. You are interrupting the string by using double quotes inside of double quotes.

echo "<li><a href='#{$child->name}' onClick='$.scrollTo( '#{$child->name}', 800 );'>{$child->title}</a></li>";
 

When using $ as a char within doublequotes in PHP, (and not to indicating a Variable), it should be escaped with a \ (backslash).

When using a $ as char within singlequotes, escaping is not necessary.

 

That is because PHP treats strings in singlequotes 'as is' (no further processing is done on it), whereas strings in doublequotes will be parsed and every found variable get replaced by it's value.

 

So, the above example will work in PHP, but will not provide correct code to work with the javascript in your page! The problem with Diogos example is that it breaks the onClick value. To avoid this you have to use escaped doublequotes for the onclick value and within that value singlequotes (for the string that get passed to the javascript function):

echo "<li><a href='#{$child->name}' onClick=\"$.scrollTo( '#{$child->name}', 800 );\">{$child->title}</a></li>";

  • Like 1
Link to comment
Share on other sites

As always the simplest answers save the day. It's working perfectly now.  Thank you so much guys!

One last question.  My original link setup used a class to highlight whatever link was active on the page like so.

<ul class="nav">
  <li class="active"><a href="#">Home</a></li>
  <li><a href="#">Link 2 etc</a></li>
</ul>

How would I add this to the new code?

Link to comment
Share on other sites

In your case this has to be done with javascript. Using jQuery you could something like this:

$('ul.nav li a').click(function(){
    $(this).parent().addClass('active').siblings('.active').removeClass('active');
});

But this will only work when clicking the links, It won't change automatically as you scroll. For this you would have to test for the position of the elements on the screen.

Link to comment
Share on other sites

  • 3 years later...

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...