Lesson 7: Managing Pages
| filename: | lesson07-manage_pages.py |
| getName() | Lesson 07 - Manage Pages |
| getDescription() | Lesson 07 - Learn how to manage pages via the plugin API |
Let's be honest. Last lesson was a bit of a holiday. Only one new function - remove a book - not exactly a stretch. But now
it's time to accelerate again. We're going to learn all about pages. Writing pages is really the core purpose of Note Studio,
so this is probably the most important lesson in the whole series - it's just that we've had to get through the all of the
previous lessons for this lesson to make sense!
Something Old, Something New
Let's refresh our minds with some stuff we covered a while ago. In lesson 3, we saw how to get page names and page contents.
If we have a WikiBook object called 'book', then we can get them like so:
Page Name:
numPages = book.getNumPages() for i in range( numPages ): pageName = book.getPageName( i )
Page Contents:
page = book.getPage( i ) rawText = page .getText()
Another Page Name
You're going to see another way to get the page name. In the above method, it's accessed by calling 'getPageName()', which is a method of the WikiBook object.
There's also a 'getName()' method on the WikiPage object itself:
page = book.getPage( i ) pageName = page.getName()
So, when would you use each method? Why are there two methods?
Well, it comes down to performance.
If you are iterating through all pages in a book, WikiBook.getPageName() method can be significantly faster than WikiPage.getName(). This is because when you create a book object, it immediately contains all of the page names. So WikiBook.getPageName() simply requires the book to access an array element from RAM.
WikiPage.getName(), on the other hand, creates a page object for each page. This means a file has to be read from the disk, and a lot of initialization
has to be done on the page object, before you can query its name.
So which method to use? If you need to create the page object for other reasons anyway, you may as well use WikiPage.getName(). But if you can avoid creating the page object, it's preferable to use WikiBook.getPageName().
Creating a Page
Alright, enough background. Let's look at the plugin code for this lesson. First, it does the same preliminary setup as the
previous lesson, creating a new book, with a default home page, and adding it to your first collection. Nothing new there.
So how do we add a new page to an existing book? Well, you might have some idea already. Remember how when we created a book,
and we had to add a page to ensure that the book was valid? Well, that's how you do it. We add a few different pages to the
book as follows:
book.addPageWithNameAndContents( "page 1", "This is page 1" ) book.addPageWithNameAndContents( "page 2", "This is page 2" ) book.addPageWithNameAndContents( "page 3", "This is page 3" )
Now we the book has a total of four pages - the home page plus the three new pages. Note that we did not have to connect these
new pages to any others. They are effectively floating pages, visible only via the Navigator or 'Go To Page' command. This
is completely valid.
We can then verify that:
- the page count has gone up
numPages = theAppData.library.getNumPages() outputFile.write( "Current Number of Pages: %d\n"%(numPages) )
- and that the pages are present and correct in the book:
outputFile.write( "Page Summary\n" ) outputFile.write( "#: Name - Contents\n" ) for i in range( numPages ): page = book.getPage(i) name = page.getName() text = page.getText() outputFile.write( "%d: '%s' - '%s'\n"%(i,name,text) )
Writing Page Contents
Modifying a page is done with the 'setText' function. Let's see it in action.
To each of the new pages, we're going to add a footer which points back to the Home Page. Here's how we do it. We set up an
outer loop, iterating through all pages in the book. We do it so that we can skip over the Home Page, which we've decided
does not need a footer:
def lesson07_addFooterToNewPages( outputFile, book ): outputFile.write( "\n\nin lesson07_addFooterToNewPages()\n" ) numPages = book.getNumPages() homePageName = book.getHomePage() for i in range( numPages ): page = book.getPage(i) name = page.getName() if( name == homePageName ): outputFile.write( "skipping home page '%s'\n"%homePageName ) else: outputFile.write( "adding footer to '%s'\n"%name ) addFooter( page, homePageName )
Appending a footer onto each page is done in the 'addFooter()' routine:
def addFooter( page, homePageName ): text = page.getText() text = text + "\n___\n=[[%s][go Home]]=\n"%homePageName page.setText( text )
Note that there is no special way to append or prepend text. All we can do is set the entire page contents. So if we want
to append a footer, we must first read the current contents, then manually append our text, then write the new contents.
Now, because we're having so much fun, let's modify the Home Page so that it acts as a directory listing all other pages in
the book. We construct the contents of the page, step by step:
homeText = "=This page was automatically created by a plugin=\n" homeText = homeText + "___\n" homeText = homeText + "++Directory of Pages\n" homeText = homeText + "=number of pages in directory: %d=\n"%(numPages-1)
We loop through page names, so that we can skip the Home Page:
for i in range( numPages ): name = book.getPageName(i) if( name == homePageName ): outputFile.write( "skipping home page '%s'\n"%homePageName ) else: outputFile.write( "adding directory entry for '%s'\n"%name ) homeText = homeText + "- [%s]\n"%name
Finally, when the text is complete, we set the page contents:
homePage.setText( homeText )
The directory is now complete.
Renaming a Page
Renaming a page is easy. We'll make a page called 'page 4', and rename it to 'page wookie'. The plugin code contains a lot
of logging statements, to prove that the page is actually renamed. Stripping out those logging statements, it essentially
reads:
book.addPageWithNameAndContents( oldName, "This page is going to be renamed" ) book.renamePage( oldName, newName )
As well as renaming the page, a rename page operation goes through the entire book, renaming any link which pointed to the
old page name, so you don't have to worry about doing that.
Removing a Page
No sooner have we created that page and renamed it, that we're going to remove it. By the time the plugin ends, you won't
be able to see any evidence that the page exists. Except in the output log file ('lesson07.txt'). Here's how we remove a page:
doomedPage = book.findPage( pageName ) book.removePage( doomedPage )
Like with removing a book, there is no warning message or opportunity for confirmation. The page is simply removed.
Conclusion
This has been the last part of our series on managing Note Studio data. It is not the last lesson - we haven't even popped
up a dialog or interracted with the user yet. But we have all the basic tools we need to manipulate our data. Have fun!
API Functions:
WikiBook.renamePage( oldName, newName )