teedoc plugin development
The plug-in development of teedoc
is very simple. At present, you only need to modify the template according to the template to realize the new function. If you know about python
html
css
js
, it will be easier.
The operating principle of the plugin is that teedoc
provides plugin API, write a python
package, inherit this class, and rewrite The required method (API
) is fine, the specific meaning of each method is detailed in the plugin API file Annotation
If you find that the API is unreasonable, you can submit issue to initiate a discussion and improve together~
Reference template
You can refer to default plugin
Plug-in directory structure
Here is teedoc-plugin-baidu-tongji as an example
- Create a directory, the directory name is the same as the plug-in name, it is recommended to start with
teedoc-plugin-
for easy search - Then create a
setup.py
file, this is the general configuration file of thepython
package, the most important thing in the file is to execute thesetuptools.setup()
function, the parameters mainly include the following several, more can bepython
official document search
setup(
name='teedoc-plugin-baidu-tongji',
version="1.0.2",
author='Neucrack',
author_email='xxx@xxx.com',
description='baidu tongji plugin for teedoc',
long_description=long_description, # can read from README.md
long_description_content_type="text/markdown",
url='https://github.com/Neutree/teedoc',
license='MIT',
# See https://pypi.python.org/pypi?%3Aaction=list_classifiers
classifiers=[
# Indicate who your project is intended for
'Intended Audience :: Developers',
# Pick your license as you wish (should match "license" above)
'License :: OSI Approved :: MIT License',
# Specify the Python versions you support here. In particular, ensure
# that you indicate whether you support Python 2, Python 3 or both.
'Programming Language :: Python :: 3'
],
keywords='teedoc baidu tongji',
# List run-time dependencies here. These will be installed by pip when
# your project is installed. For an analysis of "install_requires" vs pip's
# requirements files see:
# https://packaging.python.org/en/latest/requirements.html
install_requires=install_requires,
# List additional groups of dependencies here (e.g. development
# dependencies). You can install these using the following syntax,
# for example:
# $ pip install -e .[dev,test]
extras_require={
#'dev': ['check-manifest'],
#'test': ['coverage'],
},
# You can just specify the packages manually here if your project is
# simple. Or you can use find_packages().
packages=packages,
# If there are data files included in your packages that need to be
# installed, specify them here. If using Python 2.6 or less, then these
# have to be included in MANIFEST.in as well.
package_data={
"teedoc_plugin_baidu_tongji": ['assets/*'],
},
# Although'package_data' is the preferred approach, in some case you may
# need to place data files outside of your packages. See:
# http://docs.python.org/3.4/distutils/setupscript.html#installing-additional-files # noqa
# In this case,'data_file' will be installed into'<sys.prefix>/my_data'
data_files=[
],
# To provide executable scripts, use entry points in preference to the
# "scripts" keyword. Entry points provide cross-platform support and allow
# pip to create the appropriate form of executable for the target platform.
entry_points={
#'console_scripts': [
# #'gui_scripts': [
#'teedoc=teedoc-plugin-markdown-parser.main:main',
# ],
},
)
- Create package
You need to create another subfolder to store the source code. The file name is just to replace the minus sign -
in the project name with an underscore _
, because the package name in the python
code requires that the minus sign cannot be used, for example, here is teedoc_plugin_baidu_tongji
Then create a new file __init__.py
- Edit
__init__.py
To realize the function of Baidu statistics, it is actually necessary to add a script specified by Baidu statistics to the <head></head>
tags of all pages, that is, the <script></script>
tag. At the same time, from the document Get the statistical number (code
) in the configuration, the code is as follows:
import os, sys
from teedoc import Plugin_Base
from teedoc import Fake_Logger
class Plugin(Plugin_Base):
name = "teedoc-plugin-baidu-tongji"
desc = "baidu tongji support for teedoc"
defautl_config = {
}
def on_init(self, config, doc_src_path, site_config, logger = None):
'''
@config a dict object
@logger teedoc.logger.Logger object
'''
self.logger = Fake_Logger() if not logger else logger
self.doc_src_path = doc_src_path
self.site_config = site_config
self.config = Plugin.defautl_config
self.config.update(config)
self.logger.i("-- plugin <{}> init".format(self.name))
self.logger.i("-- plugin <{}> config: {}".format(self.name, self.config))
# set site_root_url env value
if not "code" in config:
self.logger.e('can not find config["code"] in plugin {}'.format(self.name))
return
baidu_tongji_code ='''<script>
var _hmt = _hmt || [];
(function() {{
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?{}";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
}})();
</script>'''.format(config["code"])
self.html_header_items = [baidu_tongji_code]
def on_add_html_header_items(self):
return self.html_header_items
You can see that class Plugin(Plugin_Base):
inherits the Plugin_Base
class, and then rewrites the on_init
and on_add_html_header_items
methods. When the document is built by teedoc
, these two functions will be called at the right time.
We obtained the Baidu statistics of the code
from the config
in the on_init
initialization function, then generated the content of the <script>
tag and stored it in the html_header_items
, and then returned it in the on_add_html_header_items
function , So that teedoc
will add this tag to the <head>
tag of all HTML
pages
- resource
Can be in setup.py
package_data={
"teedoc_plugin_baidu_tongji": ['assets/*'],
},
Specify the assets
directory and all files under it as the package data file to copy to the installation path, and then you can use the relative path (assets/
) to access in __init__.py
, which can be accessed in on_copy_files of
APICopy this file to the output directory in
, you can see the method of teedoc_plugin_search, in fact Is returning a dictionary
self.assets_abs_path = os.path.join(), "assets")
{
"/static/js/search/search_main.js": os.path.join(os.path.dirname(os.path.abspath(__file__), "assets", "search_main.js")
}
The keyword is the target path to be copied to, and the value is the absolute path of the file, and then we can refer to it in other HTML
pages through the path /static/js/search/search_main.js
Test plugin
Two methods,
One is to directly let teedoc
call the source code
It is recommended to use this method for debugging. Modifying the code only needs to re-execute teedoc serve
to take effect
- Modify a copy of the
site_config.json
file in the document root directory, and specify the source of the plug-in as the directory path
"plugins": {
"teedoc-plugin-baidu-tongji":{
"from": "Path",
"config": {
"code": "9cb07365532534256c346c838181a"
}
}
},
Then execute teedoc serve
in the document root directory.
Another way is to install the plug-in directly to the system and let teedoc
call the package
Using this method, you need to go through the following steps every time you change the code to modify the code, which is more troublesome than the above method. You can use this method to test the usability before releasing the plug-in.
- Install plugin
After the plug-in is written, execute it in the plug-in root directory (the directory with the setpu.py
file)
pip install.
Pay attention to the .
symbol not to be ignored
The plugin will be installed to the system as a python
package
- Then execute
teedoc serve
in the document root directory.
Pay attention
Because the build will use multiple processes, so there are some places to pay attention to
- Plug-in initialization:
__init__()
function cannot be overridden, plug-in initialization can useon_init()
oron_new_process_init()
;on_init()
is called when the plugin is initialized, and general data can be initialized here. When multiple processes are created, the data of the plug-in will be copied to the new process for use. For some objects that cannot be directly copied by multiple processes, please initialize inon_new_process_init()
on_new_process_init()
is called when multiple processes are created, such as here In this function to initialize themarkdown
renderer instead of in theon_init()
, because you don’t want to copy theself.md_parser
object when a new process is created, but each new process is rebuilt independently Create an object
- The same
__del__()
function cannot be used, but useon_del()
oron_new_process_del()
function - In plugin.py the functions behind
on_new_process_init()
may be in a new process (multi-process) Called, while the previous function will only be called in the main process
Publish plugin
The release method of the plug-in is the release method of the ordinary python
package, published to pypi.org
- Execute the command in the root directory of the plug-in to generate the release package:
python setup.py bdist_wheel sdist
Register an account at pypi.org
Then upload to
pypi.org
twine upload dist/*
- Then users can directly fill in your plugin name in
site_config.json
to use
It can also be installed via pip
:
pip install your plugin name