1. Remove index.php from the URL. (I usually use the “File and Directory Check” method.)
2. Make a new template group with “blog” as the Template Group Name. If you use the index template you don’t need “index” in the URLs.
3. Check the URL Segment Variables. Segment 2 should be the year, segment 3 should be the month, and segment 4 should be the URL title. Here’s some code to test:
Segment 1: {segment_1}<br />
Segment 2: {segment_2}<br />
Segment 3: {segment_3}<br />
Segment 4: {segment_4}<br />
4. Use conditional variables to (a) show the most recent entries (or whatever) if there isn’t a year, month, and URL title in the URL, (b) show the yearly archives if there’s a year but not a month, (c) show the monthly archives if there’s a month but not a URL title, (d) display the weblog entry if segment 4 is a valid URL title, and (e) redirect to the 404 message if segment 4 isn’t a valid URL title.
{if segment_2 == ''}
{!-- show the most recent entries --}
{/if}
{if segment_2 != '' && segment_3 == ''}
{!-- show the yearly archive --}
{/if}
{if segment_2 != '' && segment_3 != '' && segment_4 == ''}
{!-- show the monthly archive --}
{/if}
{if segment_4 != ''}
{exp:weblog:entries weblog="blog" url_title="{segment_4}" require_entry="yes" limit="1" dynamic="off"}
{title}
{if no_results}
{redirect="404"}
{/if}
{/exp:weblog:entries}
{/if}
The exp:weblog:entries tag uses the url_title and require_entry parameters to display the entry, and the if no_results conditional variable to redirect to the 404 message. (You could also pass the year and month as parameters if you wanted to require that the year and month in the URL match the entry.)
Edit: added dynamic=“off” parameter.
I’d use embedded templates to keep things simple. You might need to disable strict URLs
Finally, build your links to the blog posts:
{exp:weblog:entries weblog="blog"}
{if count == '1'}<ul>{/if}
<li>[a href="/blog/{entry_date format="%Y/%m"}/{url_title}/"]{title}[/a]</li>
{if count == total_results}</ul>{/if}
{/exp:weblog:entries}
(Note: I changed angled brackets to square ones so the code would display accurately.)