You don't need to deploy a custom page layout but you do need to use code. The way we have solved this is to create an Event Receiver for the WebProvisioned event which will fire after a new SPWeb has been created.
What you can do is to update the PublishingPage in the new web with the Page Layout that you want. This allows users to create new webs but you to set the default Page Layout of each new web.
This is the event receiver code:
public override void WebProvisioned(SPWebEventProperties properties)
{
try
{
if (PublishingWeb.IsPublishingWeb(properties.Web))
{
PublishingWeb curPubWeb = PublishingWeb.GetPublishingWeb(properties.Web);
foreach (PageLayout curLayout in curPubWeb.GetAvailablePageLayouts())
{
if (curLayout.Name == "DefaultPageLayout.aspx")
{
foreach (PublishingPage curPage in curPubWeb.GetPublishingPages())
{
curPage.CheckOut();
curPage.Layout = curLayout;
curPage.Update();
curPage.CheckIn("");
}
break;
}
}
}
}
catch (Exception ex)
{
/* Handle exception here */
}
}
And this is the code to register the event receiver (this can be run when your feature is activated or can be run once from a PowerShell script or console application):
using (SPSite topSite = new SPSite("[Site Collection URL]"))
{
SPEventReceiverDefinition webEventDef = topSite.EventReceivers.Add();
webEventDef.Name = "Web Adding Receiver";
webEventDef.Synchronization = SPEventReceiverSynchronization.Synchronous;
webEventDef.Type = SPEventReceiverType.WebProvisioned;
webEventDef.SequenceNumber = 4001;
webEventDef.Assembly = "MyCustomAssembly, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=123456789";
webEventDef.Class = "MyCustomAssembly.CustomEvents";
webEventDef.Data = "Adding publishingwebfeatures";
webEventDef.Update();
}