Skip to content

Commit

Permalink
Avoid using the app package as a hardcoded string (#1029)
Browse files Browse the repository at this point in the history
* Add template filters and TethysBase classmethods to use inplace of ``django.shortcuts`` functions to avoid using the ``app.package`` as a magic string

* tests

* Change scaffold to use `App` and `Extension` rather than custom names.
Update docs to reflect
Consolidate template tags/filters to all use the `tethys` namespace.

* Add database engine config to install script

* Update docs/tutorials/google_earth_engine/part_2/about_page.rst

Co-authored-by: Nathan Swain <swainn@users.noreply.github.com>

* Debug CI tests

* add render_to_string
fix bug with job's table refresh

* Add templatetags module to tethys_sdk

---------

Co-authored-by: Nathan Swain <swainn@users.noreply.github.com>
  • Loading branch information
sdc50 and swainn committed Apr 11, 2024
1 parent cf6ebe6 commit 9d5c55b
Show file tree
Hide file tree
Showing 133 changed files with 830 additions and 515 deletions.
Expand Up @@ -100,6 +100,7 @@ Use these build arguments with the ``build`` command to customize how the image
+---------------------------+------------------------------------------------------------------------------------------+
| MICRO_TETHYS | Set to True to use `micro-tethys` environment. Defaults to False. |
+---------------------------+------------------------------------------------------------------------------------------+

Important Paths
---------------

Expand Down Expand Up @@ -166,6 +167,7 @@ These environment variables are used to configure the database and database user
+--------------------------+-------------------------------------------------------------------------------------------------------------------------------------+
| SKIP_DB_SETUP | Set to True to skip database creation, useful for existing databases configured for Tethys. Defaults to False. |
+--------------------------+-------------------------------------------------------------------------------------------------------------------------------------+

Tethys Portal Admin User
------------------------

Expand Down
8 changes: 7 additions & 1 deletion docs/tethys_sdk/app_class.rst
Expand Up @@ -104,4 +104,10 @@ Class Methods

.. automethod:: tethys_apps.base.TethysAppBase.create_persistent_store

.. automethod:: tethys_apps.base.TethysAppBase.drop_persistent_store
.. automethod:: tethys_apps.base.app_base.TethysAppBase.render

.. automethod:: tethys_apps.base.app_base.TethysBase.redirect

.. automethod:: tethys_apps.base.app_base.TethysBase.reverse

.. automethod:: tethys_apps.base.app_base.TethysBase.render_to_string
5 changes: 3 additions & 2 deletions docs/tethys_sdk/extensions/custom_gizmos.rst
Expand Up @@ -237,6 +237,7 @@ Import and create a new instance of the gizmo in your controller:
::

from tethysext.my_first_extension.gizmos import CustomSelectInput
from .app import App


def my_app_controller(request):
Expand All @@ -253,13 +254,13 @@ Import and create a new instance of the gizmo in your controller:
context = {
'my_select': my_select,
}
return render(request, 'my_first_app/a_template.html', context)
return App.render(request, 'a_template.html', context)

Then use the gizmo as usual in ``a_template.html``:

.. code-block::django
{% load tethys_gizmos %}
{% load tethys %}
{% gizmo my_select %}
4 changes: 2 additions & 2 deletions docs/tethys_sdk/extensions/models.rst
Expand Up @@ -47,7 +47,7 @@ To use the extension models to query the database, import them from the extensio

::

from tethysapp.my_first_app.app import MyFirstApp as app
from tethysapp.my_first_app.app import App
from tethysext.my_first_extension.models import Project


Expand All @@ -63,4 +63,4 @@ To use the extension models to query the database, import them from the extensio
'project': project
}

return render(request, 'my_first_app/some_template.html', context)
return App.render(request, 'some_template.html', context)
8 changes: 5 additions & 3 deletions docs/tethys_sdk/extensions/templates_and_static_files.rst
Expand Up @@ -4,20 +4,22 @@ Templates and Static Files

**Last Updated:** February 22, 2018

Templates and static files in extensions can be used in other apps. The advantage to using templates and static files from extensions in your apps is that when you update the template or static file in the extension, all the apps that use them will automatically be updated. Just as with apps, store the templates in the ``templates`` directory and store the static files (css, js, images, etc.) in the ``public`` directory. Then reference the template or static file in your app's controllers and templates using the namespaced path.
Templates and static files in extensions can be used in other apps. The advantage to using templates and static files from extensions in your apps is that when you update the template or static file in the extension, all the apps that use them will automatically be updated. Just as with apps, store the templates in the ``templates`` directory and store the static files (css, js, images, etc.) in the ``public`` directory. When using an extension template in your app's controllers, import the extension and use it to render the templates.

For example, to use an extension template in one of your app's controllers:

::

from tethysext.my_first_extension import Extension as MyFirstExtension

def my_controller(request):
"""
A controller in my app, not the extension.
"""
...
return render(request, 'my_first_extension/a_template.html', context)
return MyFirstExtension.render(request, 'a_template.html', context)

You can reference static files in your app's templates using the ``static`` tag, just as you would any other static resource:
You can reference static files in your app's templates using the ``static`` tag, just as you would any other static resource. However, rather than using the ``public`` filter to namespace the file path for you, you will need to the use the namespaced path (i.e. include the extension package name):

.. code-block:: html

Expand Down
15 changes: 10 additions & 5 deletions docs/tethys_sdk/gizmos.rst
Expand Up @@ -32,6 +32,7 @@ In this case, we import ``DatePicker`` and initialize a new object called ``date
::

from tethys_sdk.gizmos import DatePicker
from .app import App

def gizmo_controller(request):
"""
Expand All @@ -50,18 +51,18 @@ In this case, we import ``DatePicker`` and initialize a new object called ``date

context = {'date_picker': date_picker}

return render(request, 'my_first_app/template.html', context)
return App.render(request, 'template.html', context)

The :ref:`gizmo_options` section provides detailed descriptions of each Gizmo option object, valid parameters, and examples of how to use them.

2. Load Gizmo Library in Template
---------------------------------

Now near the top of the template where the Gizmo will be inserted, load the ``tethys_gizmos`` library using the `Django load tag <https://docs.djangoproject.com/en/1.9/ref/templates/builtins/#load>`_. This only needs to be done once per template:
Now near the top of the template where the Gizmo will be inserted, load the ``tethys`` library using the `Django load tag <https://docs.djangoproject.com/en/1.9/ref/templates/builtins/#load>`_. This only needs to be done once per template:

::

{% load tethys_gizmos %}
{% load tethys %}


4. Insert the Gizmo
Expand Down Expand Up @@ -96,7 +97,11 @@ The Gizmo Showcase App provides live demos and code examples of every Tethys Giz
API Documentation
=================

This section contains a brief explanation of the template tags that power Gizmos. These are provided by the ``tethys_gizmos`` library that you load at the top of templates that use Gizmos.
This section contains a brief explanation of the template tags that power Gizmos. These are provided by the ``tethys`` library that you load at the top of templates that use Gizmos.

.. code-block:: html+django

{% load tethys%}

**gizmo**
---------
Expand Down Expand Up @@ -150,7 +155,7 @@ Tells the ``gizmo_dependencies`` to load in the dependencies for the gizmo. This
**gizmo_dependencies**
----------------------

Inserts of the CSS and JavaScript dependencies at the location of the tag for all gizmos loaded in the template with the **gizmo** tag. This tag must appear after all occurrences of the ``gizmo`` tag. In Tethys Apps, these depenencies are imported for you, so this tag is not required. For external Django projects that use the tethys_gizmos Django app, this tag is required.
Inserts of the CSS and JavaScript dependencies at the location of the tag for all gizmos loaded in the template with the ``gizmo`` tag. This tag must appear after all occurrences of the ``gizmo`` tag. In Tethys Apps, these dependencies are imported for you, so this tag is not required. For external Django projects that use the tethys_gizmos Django app, this tag is required.

*Parameters*:

Expand Down
5 changes: 3 additions & 2 deletions docs/tethys_sdk/gizmos/bokeh_view.rst
Expand Up @@ -55,6 +55,7 @@ Three elements are required:
from tethys_sdk.gizmos import BokehView
from tethys_sdk.routing import controller
from bokeh.plotting import figure
from .app import App
@controller(name="bokeh_ajax", url="app-name/bokeh")
def bokeh_ajax(request):
Expand All @@ -67,13 +68,13 @@ Three elements are required:
context = {'bokeh_view_input': my_bokeh_view}
return render(request, 'app_name/bokeh_ajax.html', context)
return App.render(request, 'bokeh_ajax.html', context)
2) A template for with the tethys gizmo (e.g. bokeh_ajax.html)

.. code-block:: html+django

{% load tethys_gizmos %}
{% load tethys %}

{% gizmo bokeh_view_input %}

Expand Down
4 changes: 2 additions & 2 deletions docs/tethys_sdk/gizmos/cesium_map_view.rst
Expand Up @@ -71,13 +71,13 @@ Three elements are required:
context = { "cesium_map_view": cesium_map_view }
return render(request, "dam_break_map_ajax/map_ajax.html", context)
return App.render(request, "map_ajax.html", context)
2) A template for with the tethys gizmo (e.g. map_ajax.html)

.. code-block:: html+django

{% load tethys_gizmos %}
{% load tethys %}

{% gizmo cesium_map_view %}

Expand Down
5 changes: 3 additions & 2 deletions docs/tethys_sdk/gizmos/datatable_view.rst
Expand Up @@ -33,6 +33,7 @@ Three elements are required:
.. code-block:: python
import json
from .app import App
@controller
def datatable_ajax(request):
Expand All @@ -57,13 +58,13 @@ Three elements are required:
context = {"datatable_options": datatable_default}
return render(request, "app_name/datatable_ajax.html", context)
return App.render(request, "datatable_ajax.html", context)
2) A template for with the tethys gizmo (e.g. datatable_ajax.html)

.. code-block:: html+django

{% load tethys_gizmos %}
{% load tethys %}

{% gizmo datatable_options %}

Expand Down
4 changes: 2 additions & 2 deletions docs/tethys_sdk/gizmos/map_view.rst
Expand Up @@ -288,13 +288,13 @@ Three elements are required:
context = { "map_options": map_options }
return render(request, "dam_break_map_ajax/map_ajax.html", context)
return App.render(request, "map_ajax.html", context)
2) A template for with the tethys gizmo (e.g. map_ajax.html)

.. code-block:: html+django

{% load tethys_gizmos %}
{% load tethys %}

{% gizmo map_options %}

Expand Down
6 changes: 4 additions & 2 deletions docs/tethys_sdk/gizmos/plot_view.rst
Expand Up @@ -81,6 +81,8 @@ Three elements are required:

.. code-block:: python
from .app import App
@controller(
url="dam-break/map/hydrograph",
)
Expand All @@ -96,13 +98,13 @@ Three elements are required:
context = {"flood_plot": flood_plot}
return render(request, "dam_break/hydrograph_ajax.html", context)
return App.render(request, "hydrograph_ajax.html", context)
2) A template for with the tethys gizmo (e.g. hydrograph_ajax.html)

.. code-block:: html+django

{% load tethys_gizmos %}
{% load tethys %}

{% gizmo flood_plot %}

Expand Down
5 changes: 3 additions & 2 deletions docs/tethys_sdk/gizmos/plotly_view.rst
Expand Up @@ -56,6 +56,7 @@ Three elements are required:
import plotly.graph_objs as go
from tethys_sdk.gizmos import PlotlyView
from tethys_sdk.routing import controller
from .app import App
@controller(name='plotly_ajax', url='app-name/plotly')
Expand All @@ -71,13 +72,13 @@ Three elements are required:
context = {'plotly_view_input': my_plotly_view}
return render(request, 'app_name/plotly_ajax.html', context)
return App.render(request, 'plotly_ajax.html', context)
2) A template for with the tethys gizmo (e.g. plotly_ajax.html)

.. code-block:: html+django

{% load tethys_gizmos %}
{% load tethys %}

{% gizmo plotly_view_input %}

Expand Down
5 changes: 3 additions & 2 deletions docs/tethys_sdk/gizmos/select_input.rst
Expand Up @@ -34,6 +34,7 @@ Three elements are required:
.. code-block:: python
from tethys_sdk.gizmos import SelectInput
from .app import App
@controller(
url="app_name/select",
Expand All @@ -50,13 +51,13 @@ Three elements are required:
context = {"select_input2": select_input2}
return render(request, "app_name/select_input_ajax.html", context)
return App.render(request, "select_input_ajax.html", context)
2) A template for with the tethys gizmo (e.g. select_input_ajax.html)

.. code-block:: html+django

{% load tethys_gizmos %}
{% load tethys %}

{% gizmo select_input2 %}

Expand Down
5 changes: 3 additions & 2 deletions docs/tethys_sdk/gizmos/toggle_switch.rst
Expand Up @@ -33,6 +33,7 @@ Three elements are required:
.. code-block:: python
import json
from .app import App
@controller
def toggle_ajax(request):
Expand All @@ -45,13 +46,13 @@ Three elements are required:
context = {"toggle_switch": toggle_switch}
return render(request, "app_name/toggle_ajax.html", context)
return App.render(request, "toggle_ajax.html", context)
2) A template for with the tethys gizmo (e.g. toggle_ajax.html)

.. code-block:: html+django

{% load tethys_gizmos %}
{% load tethys %}

{% gizmo toggle_switch %}

Expand Down
10 changes: 5 additions & 5 deletions docs/tethys_sdk/jobs.rst
Expand Up @@ -58,13 +58,13 @@ To use the Job Manager in your app you first need to import the TethysAppBase su

::

from app import MyFirstApp as app
from .app import App

You can then get the job manager by calling the method ``get_job_manager`` on the app.

::

job_manager = app.get_job_manager()
job_manager = App.get_job_manager()

You can now use the job manager to create a new job, or retrieve an existing job or jobs.

Expand Down Expand Up @@ -197,7 +197,7 @@ The Jobs Table Gizmo facilitates job management through the web interface and is

::

job_manager = app.get_job_manager()
job_manager = App.get_job_manager()

jobs = job_manager.list_jobs(request.user)

Expand All @@ -209,7 +209,7 @@ The Jobs Table Gizmo facilitates job management through the web interface and is
striped=False,
bordered=False,
condensed=False,
results_url='app_name:results_controller',
results_url=f'{App.package}:results_controller',
)

.. seealso::
Expand Down Expand Up @@ -238,7 +238,7 @@ This URL can be retrieved from the job manager with the ``get_job_status_callbac

::

job_manager = app.get_job_manager()
job_manager = App.get_job_manager()
callback_url = job_manager.get_job_status_callback_url(request, job_id)

API Documentation
Expand Down
9 changes: 6 additions & 3 deletions docs/tethys_sdk/jobs/condor_job_type.rst
Expand Up @@ -31,11 +31,14 @@ To create a job call the ``create_job`` method on the job manager. The required

.. code-block::
from tethysapp.my_first_app.app import MyFirstApp as app
from tethys_sdk.workspaces import app_workspace
from tethys_sdk.routing import controller
from .app import App
job_manager = App.get_job_manager()
@app_workspace
@controller(
app_workspace=True,
)
def some_controller(request, app_workspace):
# create a new job from the job manager
job = job_manager.create_job(
Expand Down

0 comments on commit 9d5c55b

Please sign in to comment.