Package: discord-ext-pager
discord-ext-pagerA simple view-based paginator library for discord.py 2.0. Works with Python 3.8+.Usagediscord-ext-pageris available on PyPI, and as such can be installed using pip.Users of Danny'sdiscord-ext-menuswill find some familiarity
in this library. Provided are the following classes:PaginatorView:
The view class that manages pagination and navigation.PageSource:
The base class for sources the paginator view can accept.ListPageSource:
The base class for formatting a list of items.AsyncIteratorPageSource:
The base class for formatting an asynchronous iterator of items.PageOption:
A subclass ofdiscord.SelectOptionused for presenting navigation options.StopAction:
An enum for customizing PaginatorView's stop button behaviour.TimeoutAction:
An enum for customizing PaginatorView's timeout behaviour.ThePaginatorViewcan be instantiated and used by itself, but page formatting
is handled by subclassing one of thePageSourcebase classes.fromtypingimportListfromdiscord.ext.pagerimportListPageSource,PageSource,PaginatorViewclassEmbedListPageSource(ListPageSource[object,PageSource,PaginatorView]):#                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^#            These type parameters denote the page item type,#            source type for page options (demonstrated later),#            and view type. Only needed for static typing."""Takes a list of items and formats it in an embed."""defformat_page(self,view:PaginatorView,page:List[object]):index=self.current_index*self.page_sizedescription="\n".join(f"{i}.{x}"fori,xinenumerate(page,start=index+1))returndiscord.Embed(description=description)# Anywhere a channel or interaction is available:fruits=["🍎 Apple","🍊 Orange","🍋 Lemon"]source=EmbedListPageSource(fruits,page_size=2)view=PaginatorView(sources=source,timeout=180)awaitview.start(interaction)If the navigation select menu is desired, theget_page_options()method
should be overridden to return a list ofPageOptionobjects for the user
to select from:fromtypingimportListfromdiscord.ext.pagerimportListPageSource,PageOption,PageSource,PaginatorViewclassMessageSource(PageSource[str,PageSource,PaginatorView]):"""A single page for displaying a string."""def__init__(self,message:str):super().__init__(current_index=0)self.message=messagedefget_page(self,index:int):returnself.messagedefformat_page(self,view:PaginatorView,page:str):# If we don't specify both content and embed, either will# persist as the user clicks between optionsreturn{"content":page,"embed":None}classMessageNavigator(ListPageSource[MessageSource,MessageSource,PaginatorView]):"""A list of messages for the user to select from."""defget_page_options(self,view:PaginatorView,page:List[MessageSource]):# PageOption() takes the same arguments as discord.SelectOption,# except that source= is also requiredreturn[PageOption(source=source,label=source.message)forsourceinpage]defformat_page(self,view:PaginatorView,page:List[MessageSource]):description="\n".join(source.messageforsourceinpage)embed=discord.Embed(description=description)return{"content":None,"embed":embed}hands="👈👉👆👇🫵🤞🫰🤘🤙🤛🤜✊👊👋👏🙌"source=MessageNavigator([MessageSource(s)forsinhands],page_size=5)view=PaginatorView(sources=source)awaitview.start(ctx)When an option is selected, thePageSourcecontained within that option
is appended toPaginatorView.sources, causing that source to be displayed.
Another button is automatically provided for users to back out to the last
page source. This can be manually triggered by passing a list of page sources
to thePaginatorView(sources=)argument.ExamplesClick on an example below to see its source code: