Forum Moderators: coopster

Message Too Old, No Replies

PHP to Dynamically make new pages? DOH!

php, dynamically make new page, create pages

         

diegomh7

9:59 am on Aug 18, 2005 (gmt 0)

10+ Year Member



Ok guys heres one I've been dodging for a while but a new client wants it so...

I am building a CMS system for a client to edit add and remove content from his new site, not a problem however he now wants the facility to create new pages and be able to edit the new pages, how do you create a new page dynamically using php and mysql?

As in he needs to make a new page called untitled2.php for example, with the title at the top of the page, a description about untitled 2 and then save the newly created page so it appears in the menu and actually exists in the remote server files, then be able to edit this using the CMS system? ERM...

Any standard commands as in create_page()?

How would I make the new page have variables included so that it could echo mysql content onto the newly created page?

breaking my head scanning google for tutorials,

help would be more than appreciated,

diegomh7

:D

mcibor

10:42 am on Aug 18, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



fopen [php.net] with some parameter will create file

$i = 1;
while($file = fopen("untitled$i.html", "r")) {fclose($file); $i++}//do nothing - you need a file that doesn't exist
//now we have an untitled12.html which doesn't exist, so you need to create it:
if($file = fopen("untitled$i.html", "w")) {// Open for writing only; place the file pointer at the beginning of the file and truncate the file to zero length. If the file does not exist, attempt to create it.
$html = "<html>\n<body>\n<p>Hello world</p>\n</body>\n</html>";
if(fwrite($file, $html) === false) echo "Could not write to file untitled$i.html";
else echo "Write successful!";
fclose($file);
}

Now you need just link.
However I would suggest naming the file first, because I don't know of any way to rename the file after creation
Best regards
Michal Cibor

StupidScript

5:58 pm on Aug 18, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Building on mcibor's fine suggestion:

<?

if ($_POST["filename"]) {

error_reporting(0);

$i=1;

while($file = fopen("untitled$i.html", "r")) { fclose($file); $i++; }

if($file = fopen("untitled$i.html", "w")) {

$html = "<html>\n<body>\n<p>Hello world</p>\n</body>\n</html>";

if(fwrite($file, $html) === false) { echo "Could not write"; exit; }

fclose($file);

$newfile=$_POST["filename"].".html";

system("mv untitled$i.html $newfile");

header("Location: $newfile");

}

}

else {

echo "<form method=post action='".$_SERVER["SCRIPT_NAME"]."'>\n";

echo "New File Name: <input name='filename'>\n</form>\n";

}

?>

Windows:

system("ren untitled$i.html $newfile");

'Nix

system("mv untitled$i.html $newfile");

StupidScript

11:57 pm on Aug 18, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



while($file = fopen("untitled$i.html", "r")) { fclose($file); $i++; }

could easily be:

$newfile=$_POST["filename"].".html";

while($file = fopen($newfile, "r")) {

fclose($file);

echo "File already exists.";

}

and so on, but I wanted to build on mcibor's example as a logical way of looking at the activity.

delboy1978uk

12:16 am on Aug 19, 2005 (gmt 0)

10+ Year Member



You are actually much better NOT making a new page - Remember - the whole point of creating CMS is to stop all that crap -

What you need is a page for inserting a new record into a database, and a page for viewing each "new" page

The input page will be fields for Heading, Paragraph, and BLOB file for any images - you will need to code the ability for him to upload an image though - ask someone else

Whole point is you make an add edit delete page for each record (page)(your client doesn't know any better and thats why he says page)

delboy1978uk

12:18 am on Aug 19, 2005 (gmt 0)

10+ Year Member



so long as the pages all follow the same format that is

diegomh7

12:58 pm on Aug 19, 2005 (gmt 0)

10+ Year Member



Hmmm, Thanx for all the help guys, Im gonna have a sit down and decide on what to do bout this one, I can get my head round making a (template page) bringing an id from the database and filling the page with the record details for that id, how do I add the filename to the navbar?

Could I make the nav be stored in the db in a table called nav for example, then when they are creating the new page and (naming) it, store the name in the db table nav, then the link (id) is stored there so that when it comes to the page the browser gets the id from the link and drags the record up into the template (newpage)?

owww confusing myself now, think im on the right track though,

I do also like the idea if having a template page and fopen() it, then edit stuff like, but could the id way be easier?

any more ideas wonderful world? :D

dlefree

2:00 am on Aug 20, 2005 (gmt 0)

10+ Year Member



I'm working on (surprise, surprise) the exact same thing - here's what I've locked in...

Components:

Database - Create a new entry in your "pages" or "content" table (as you noted, it'd be best to handle links separately for one's sanity's sake)

Administration page for adding / updating / deleting "pages" - Simple form (perhaps with some parsing to allow for shortcuts in the HTML code, not unlike BBCode) to get pages into the database

Template - Generic template which serves up the database content

Caching system - Save processing overhead by saving a copy of your database content in a separate include file (might tie in pretty handily with a "Publish" feature?)

.htaccess Redirect system for simulating new pages - Theoretically, your entire "file system" could reside within index.php, if you can put together a solid HTACCESS redirection system to rewrite queries to index.php as ".PHP" or ".HTM" file requests...

Execution:

- User requests a page (i.e. "/widget-content/index.htm")

- .htaccess rewrite rules translate this to: "/index.php?content_category=widget-content&page=index"

- A transparent redirect (no redirect code sent) calls up the template page (index.php) with the cached include file

Considerations:

- If $_GET query returns no results, have index.php script redirect user to a 404 page

- Include directive in .htaccess file to redirect "/index.php?category_name=x&page=x" requests to the appropriate URL format (ensuring duplicate content penalties are not accidentally encountered)

Let me know if you're planning on running with this setup - I can probably point you in the direction of some decent resources.

StupidScript

5:06 pm on Aug 22, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



The question arises: How do database-only sites do in the SERPs? If it's all one template with query strings, does that work out well compared to the same content in a "traditional", hard-coded multi-page site?

Tapolyai

5:18 pm on Aug 22, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Most forum based systems are database driven.

That is - the pages for the forums are from a DB. It the case of WebmasterWorld, this is, I presume, done through a perl script, but many others like phpBB, and vBulletin uses PHP with mySQL.

I believe they are well positioned in SERP.

StupidScript

6:00 pm on Aug 22, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



So, like this forum, Apache's mod_rewrite is what does the trick? I see the URL is pretty normal, here.

Tapolyai

1:39 am on Aug 23, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



It does not look like it. If you look at the source, the links are full URLs. But search engines that worth a cent, can and do spider sites with very complex URLs, with several variables, even with session IDs now.

Of course, most forum software packages now also recognized the most well known ones, and adjust accordingly. For example both phpBB and vBulletin see Googlebot, and "remove" the session ID. vBulletin even has a "flat clean" archive for feeding the variety of spiders.

TravelSite

10:33 am on Aug 23, 2005 (gmt 0)

10+ Year Member



I use the method that dlefree suggested.

htaccess redirects all page requests to a main "page.php" script. This script looks for the url requested in a database table of "pages". If found then the page is loaded into a variable. I then use the following function:

eval('?>' . $master_include_file . '<?php ');

This function allows all php code in that variable/"page" to be executed. I'm not sure how this effects speed / processing power required.

DaButcher

11:17 am on Aug 23, 2005 (gmt 0)

10+ Year Member



I found some script on www.evolt.org ages ago, which I modified..

I rebuild a querystring, based on the fake url and then I gather the variables I want..

this gives me the opportunity to "fake url"..
eg:
domaint.tld/foo/bar_1/lala_2/qasdoasdoasd/random/random

foo is the file, which is an extensionless file.
bar will be a variable, with value = 1
lala will be a vaariable with value = 2
the rest is only mumbojumbo..

one can rearrange too, like:

domain.tld/keyword/keyword/bar_1/lala_2

it will produce the same result.

then you can use the variables for querying db and retrieving content.

henry0

11:29 am on Aug 23, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Naming the page and url

Name: use a concatenation for ex: I did break it in many chuncks for demo purposes.
$begin_url= "<a href=\"index" ;
$p=".php";
$end="\">" ;
$file_name="myPage";
$a="</a><br>";

//concatenation
$url= $begin_url.$p.$end.$php.$file_name.$a;

URL:
Load that in your db
Create a simple nav system the exists upon DB data
So if a new row exists it will be loaded in your nav system

For the rest as metioned above have a template (you may have a few models)
Copy, name it, create url, call for it.

diegomh7

11:43 am on Aug 23, 2005 (gmt 0)

10+ Year Member



This is all good but we have totally gone of helping me sort out the best way to solve my problem lol,

ideas,

Dildego

henry0

11:57 am on Aug 23, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Dildego

Are you implementing an existing solution out of a tutorial.

or did you hard code your own CMS?

diegomh7

12:02 pm on Aug 23, 2005 (gmt 0)

10+ Year Member



Im going to hard code the cms myself, in php, done it before a few times, editing, deleting, adding, images, etc however ive never had to add new pages dynamically or add the the navbar dynamically aswell, thats why im looking for the best way to approach it b4 I get moving on it properly,

thx

henry0

12:33 pm on Aug 23, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



you need a template here named TPL_DEX that will become an index or whatever page you need.
<?
// FIRST SET - COPY TPL_DEX , RENAME IT AS INDEX.PHP

// $source="../tpl_for_dupli/tpl_dex.php";
// $dest="../index.php";
$source="/pub/comwww/aaaaaa/tpl/tpl_for_dupli/tpl_dex.php";
$dest="/pub/comwww/aaaaaa/tpl/tpl_dex.php";

if (!copy($source, $dest)) {
print ("failed to copy $dest...\n");
}
echo "";
// end of copy file

// rename file

rename("/pub/comwww/aaaaaaa/tpl/tpl_dex.php", "/pub/comwww/aaaaaa/tpl/index.php");

$new_file="/pub/comwww/aaaaaaa/tpl/index.php";

//here we write to file

$fp = fopen("$new_file", "r+");
if(!$fp) die ("Hummm cannot open index");

//in ($fp,any #) the number is the precise number of bites from where we start writing data to file
for needed reasons in that example I pass the ID to the page.
fseek($fp, 52);
// HERE WE NEED THE REAL "ID" to match includes requirements; the write function passs id # to new file $id
$conn = db_connect();
$query = "select id from zzzzz where username= '$username' and page= '$page' ";
$result= mysql_query ($query);

while($query_data=mysql_fetch_array($result)) {


$byte = fwrite($fp,$query_data["id"]);
}

?>

<?
##############Here we deal with the URL making @@@@@@@@@@@@@@@
?>

<!-- // URL INDEX -->
<?
//we establish default url building
$begin_url= "<a href=\"index" ;
$p=".php";
$end="\">" ;
$file_name="Home";
$a="</a><br>";

//concatenation
$url= $begin_url.$p.$end.$php.$file_name.$a;

$query = "select url from zzzzzz where username= '$username' and page= '$page' ";
$result= mysql_query("update zzzzz set url ='$url' where username='$username' and page='$page' ");
// I used set because I had by default the row built with "url"
but you can do an insert too.
?>

the rest is easy if you need many pages built upon the same template
you need first to add means to dynanmically change the name of the page before its creation
so I will 1) copy the folder and the template - very first script action-
2) allow to name it at your will by passing a new value to rename it.
3) call the url from a field named url that will echo all url rows.

I have to go, will not be around for much of the day good luck.

diegomh7

1:56 pm on Aug 23, 2005 (gmt 0)

10+ Year Member



erm... kool I think, yeah erm, gonna have to read this a few times me thinks :D

so the template TPL_DEX.php is the main template for the new pages? And if it rewrites over the template does is save it as another page or overwrites the page each time?

Sounding like a proper noob here arent I, ill have a good look at it,

thx

henry0

3:26 pm on Aug 23, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



TPL_DEX is one kind of template
For ex:
if you need a page for a newsletter
Create a template TPL_NEWSLETTER and save that template in a dir named tpl.
Then the script does not overwrite it and does not modify del or whatever the template.
It creates a copy of the file wherever you want it.
Be advised that if you provide the wrong path in some case the template might be deleted, before testing be sure to have a back up :)

My templates are OOP oriented
So later today I can post a set of it (if you wish) adapting those will be easy if you are familiar with the OOP concept.

diegomh7

4:37 pm on Aug 23, 2005 (gmt 0)

10+ Year Member



Nice one, that would be great help, post your stuff up and Ill be able to have a nosey,

thx

henry0

9:12 pm on Aug 23, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Here you are, I have added a whole bunch of explanations so you can use it as a tutorial and an OOP intro.
Have fun.

<?
// CREATE A DIR NAMED classes & LOAD THE FOLLOWING SCRIPT IN
// NAME the script tpl_class.php
<? // an object is an instance of the class created by "Instantiation" once instantiated you may call
// the methods (Functions) defined in the class. instantiation is done through "new" Keyword
// as for example in "index" $page = new tpl_class
?>
<?php # tpl_class.php
// This class reads in a template, sets the different values, and sends it to the browser.

class tpl_class {

// Set the attributes.(functions or others..) Keyword var declares variable in class
var $template;
var $html; // var could also be var $html='..somethng..';
var $parameters = array();// or var could be as here an array();
//var $message;

function tpl_class ($template) { // This function sets which template will be used
// (see: CreatePage() where str replace replace with template name
// as per the file using the class).
// This function is a constructor it returns auto the object once setup
// the construtor accepts all vars needed in process
// we assign value to vars via $this->
$this->template = $template;
$this->html = implode ("", (file($this->template))); // Read the template into an array, implode creates a string
// representing all the array elements.
// $ this points to the object in which the function (Method) runs
// -> points to a function (Method) named within the object
}

function SetParameter ($variable, $value) { // This function sets the particular values. Parameters was
// set w/class attributes as var $parameters = array();
$this->parameters[$variable] = $value;
}

function CreatePage () { // its name says it all!

foreach ($this->parameters as $key => $value) { // Loop through all the parameters and set the variables to values.
// key in arrays is a pointer or index that returns the value of the first item placed in the array
// => is an operator that is placed after Key where the lpointer starts looping.
$template_name = '{' . $key . '}';
$this->html = str_replace ($template_name, $value, $this->html);
}
echo $this->html;
}

} // @@@@ END OF tpl_class @@@@@
?>

<?
create a dir: :tpl_for_dupli
?>
<?
/* Load in the tpl_for_dupli dir the following script and name it tpl_dex.php
as you see it call for chunk of html that are stored in an iclude
obviously instead of snipets you may load a full page
however my system allos to retain control on page making
you never want to let a client control and create a full page
*/
php # tpl_dex.php
//error_reporting (E_ALL);

$id= ;

// This is the index page that uses the tpl_class.
require_once ("include_fns_group.php"); // Include the configuration file.
require_once ("classes/tpl_class.php"); // Include the class.

$page = new tpl_class ("templates/main_template_tpl_dex.inc.php"); // Create an instance.

$page->SetParameter("PAGE_TITLE", "Business Home page");

$content_header_bg .= '';
include "includes/header_bg.inc.php";
$page->SetParameter("HEADER_BG", $content_header_bg);

$content_curve .= '';
include "includes/curve.inc.php";
$page->SetParameter("CURVE", $content_curve);

$content_logo_rect .= '';
include "includes/logo_rect.inc.php";
$page->SetParameter("LOGO_RECT", $content_logo_rect);

$content_mission_statement .= '';
include "includes/mission_statement.inc.php";
$page->SetParameter("MISSION_STATEMENT", $content_mission_statement);

$content_late_nav_svces .= '';
include "includes/late_nav_svces.inc.php";
$page->SetParameter("LATE_NAV_SVCES", $content_late_nav_svces);

$content_page_footer_html .= '';
include "includes/page_footer_html.inc.php";
$page->SetParameter("PAGE_FOOTER_HTML", $content_page_footer_html);

$footer = "Last modified " . (date("l, F j, Y", filemtime("modified.txt")));
$page->SetParameter("PAGE_FOOTER", $footer);

$page->CreatePage(); // Send the page to the browser.
unset ($page);
?>

<?
// create a dir named templates and load in the following script to be named
// main_template_tpl_dex.inc.php
?>

<! DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transactional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transactional.dtd">
<html xmlns =http://www.w3.org/1999/xhtml
xml : lang="en" lang="en">

<head>
<meta stuffs>

<link rel=stylesheet href="idx1.css" type="text/css">

</head>

<title>{PAGE_TITLE}</title>

<body topmargin="0" marginheight="0" marginwidth="0">

<table width="100%" border="0" cellspacing="0" cellpadding="0" align="center" valign="middle">
<tr>
< your <tr><td ect....>

<tr>
<td width="15%" height="60" align="left" valign="top">
{LOGO_RECT}
</td>
<td width="85%" height="60" align="center" valign="middle" {HEADER_BG}>
<div class=top_name3>
{BUSINESS_NAME}
</div></td>
</tr>

<tr>
<td width="80%" align="center" valign="top" colspan="3">
<!-- // Mission Statement -->
<div class=intro7>
{MISSION_STATEMENT}
</div>
</td>
</tr>

<!-- // lateral_nav -->
<tr>
<td width="100%" align="left" valign="top" colspan="4">
<table align="top" width="100%">
<td width="16%" align="top" valign="left">
<div class="intro1">
&nbsp; {LATE_NAV_SVCES}
</td>
<td width="16%" align="top" valign="left">
<div class="intro1">
{LATE_NAV_N_LETTER}
</td>
<td width="16%" align="top" valign="left">
<div class="intro1">
{LATE_NAV_SPECIALS}
</td>
<td width="16%" align="top" valign="left">
<div class="intro1">
{LATE_NAV_EMPL}
</td>

<!-- Well you got the idea -->

{PAGE_FOOTER_HTML} <br>
{PAGE_FOOTER}
</td></tr></table>

</body>

</html>
?>

<?
// example of includes called by tpl_dex
?>

<?
// create a dir named includes and load the include files in
?>
<?
// as per example this is mission_statement.inc.php

$conn = db_connect();
$sql= "select mission_statement from cms where id=$id";
$result = mysql_query($sql,$conn);
while ($new_content=mysql_fetch_array($result) ){
$content_mission_statement.= $new_content[mission_statement];
}
?>

[edit]added inlude file name [/edit]

jd01

11:05 pm on Aug 23, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I've been reading this one for a little while, thought I would chip in...

If you have specific directories you will be using (or not), you can implement a mod_rewrite solution that will be equally effective, and you will only have a single page template to make adjustments to...

I use this method, because if you create a new physical page every time a 'new' page based on a template is created, and you want to edit the nav or something else on those pages you have to change it on every one. My system takes a little longer to create, but maintenance is simple - make a change to the single template or the includes and the change is populated throughout.

A simple example:

3 directories mydir, somedir, otherdir

Base template is the same.

Nav for each is different, so it is an include.

Selection is different, so it is an include.

My headers and footers are different, so they are includes.

Config:
DB tables for each dir.

Each table is set with the information to be displayed:
Page Title
Page Desc.
Page Keywords
H1
Body Text
Mod_Date
Page Name
Any Other You Would Like

DB connection include is hard coded for security, only the page name for the directory is dynamic. No results found = 404.

Mod_Rewrite:
RewriteEngine ON
RewriteRule ^mydir/([^.]+)\.html /mydir.php?page=$1 [L]
RewriteRule ^somedir/([^.]+)\.html /mydir.php?page=$1 [L]
RewriteRule ^other/([^.]+)\.html /mydir.php?page=$1 [L]

This allows for simple creation of 'pages' without writing files, or creating an actual page...

It also allows the creation of an index, which can be dynamically updated with the latest additions.

Personally, I have found this much more efficeint and effective than creating 'real' pages - One site using this system has ~ 150 pages 'created' driving 8 unique directories, generated and edited by webmasters and office staff. The site is very well indexed and receives over 1M page views per month, so it appears to be effective for SEs also.

Let me know if you would like more info.

Justin

StupidScript

11:27 pm on Aug 23, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Great thread, folks.

diegomh7

12:10 am on Aug 24, 2005 (gmt 0)

10+ Year Member



indeed, lovin this!

diegomh7

aka dildego

:D

Xedium

1:00 am on Aug 24, 2005 (gmt 0)

10+ Year Member



For my own CMS, (which does not have much content), I have one script that I'll include_once. You just pass it the vars, and it'll cough up a nicely formatted section of HTML, with all the details pulled from mysql.

I don't have nav trees per se, but I'll just "select * from foo order by name asc" and while loop through all of them, each time using the included script.

I keep pics in the directory tree, but I'm not experienced at managing files in PHP.

henry0

11:42 am on Aug 24, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



JD01,
Good system.

addendum to mine:
Since the nav is dynamic editing it edits all navs.
Also my system, since I pass a specific ID to each group of pages, allows for a "mall" environment type with multiple users, multiple set of pages that cannot be edited by other than the "owner".