diff --git a/source/_static/images/import_documentation/podcast_tutorial/Mockup-Podcast-Tutorial.png b/source/_static/images/import_documentation/podcast_tutorial/Mockup-Podcast-Tutorial.png new file mode 100644 index 0000000000000000000000000000000000000000..2bebe7ff0ad43fe0eb10c6951d11f595e230a3c1 Binary files /dev/null and b/source/_static/images/import_documentation/podcast_tutorial/Mockup-Podcast-Tutorial.png differ diff --git a/source/_static/images/import_documentation/podcast_tutorial/Render1-Podcast-Tutorial.png b/source/_static/images/import_documentation/podcast_tutorial/Render1-Podcast-Tutorial.png new file mode 100644 index 0000000000000000000000000000000000000000..c081a8d4be5aa7bba03f03a83db1d09b9f43687b Binary files /dev/null and b/source/_static/images/import_documentation/podcast_tutorial/Render1-Podcast-Tutorial.png differ diff --git a/source/_static/images/import_documentation/podcast_tutorial/Render10-Podcast-Tutorial.png b/source/_static/images/import_documentation/podcast_tutorial/Render10-Podcast-Tutorial.png new file mode 100644 index 0000000000000000000000000000000000000000..3672ad5151edd72ef96d1b1d8819242f66be8bbe Binary files /dev/null and b/source/_static/images/import_documentation/podcast_tutorial/Render10-Podcast-Tutorial.png differ diff --git a/source/_static/images/import_documentation/podcast_tutorial/Render2-Podcast-Tutorial.png b/source/_static/images/import_documentation/podcast_tutorial/Render2-Podcast-Tutorial.png new file mode 100644 index 0000000000000000000000000000000000000000..5240f63b1044a688fdb81b001d46bf630f22260d Binary files /dev/null and b/source/_static/images/import_documentation/podcast_tutorial/Render2-Podcast-Tutorial.png differ diff --git a/source/_static/images/import_documentation/podcast_tutorial/Render3-Podcast-Tutorial.png b/source/_static/images/import_documentation/podcast_tutorial/Render3-Podcast-Tutorial.png new file mode 100644 index 0000000000000000000000000000000000000000..2d53cc4fb420f34df35d370785da5530591b1c93 Binary files /dev/null and b/source/_static/images/import_documentation/podcast_tutorial/Render3-Podcast-Tutorial.png differ diff --git a/source/_static/images/import_documentation/podcast_tutorial/Render4-Podcast-Tutorial.png b/source/_static/images/import_documentation/podcast_tutorial/Render4-Podcast-Tutorial.png new file mode 100644 index 0000000000000000000000000000000000000000..593e034d834a8f1538ee843fe05211839cc06e29 Binary files /dev/null and b/source/_static/images/import_documentation/podcast_tutorial/Render4-Podcast-Tutorial.png differ diff --git a/source/_static/images/import_documentation/podcast_tutorial/Render5-Podcast-Tutorial.png b/source/_static/images/import_documentation/podcast_tutorial/Render5-Podcast-Tutorial.png new file mode 100644 index 0000000000000000000000000000000000000000..ed8c7907f1d3919bb50ec2586608f70ba3588a0e Binary files /dev/null and b/source/_static/images/import_documentation/podcast_tutorial/Render5-Podcast-Tutorial.png differ diff --git a/source/_static/images/import_documentation/podcast_tutorial/Render6-Podcast-Tutorial.png b/source/_static/images/import_documentation/podcast_tutorial/Render6-Podcast-Tutorial.png new file mode 100644 index 0000000000000000000000000000000000000000..a46dbee74d4937651e70a8d99492fee51cf18dde Binary files /dev/null and b/source/_static/images/import_documentation/podcast_tutorial/Render6-Podcast-Tutorial.png differ diff --git a/source/_static/images/import_documentation/podcast_tutorial/Render7-Podcast-Tutorial.png b/source/_static/images/import_documentation/podcast_tutorial/Render7-Podcast-Tutorial.png new file mode 100644 index 0000000000000000000000000000000000000000..a961af8f3e76b0fd7f9cd489eb83ccf363a52a4b Binary files /dev/null and b/source/_static/images/import_documentation/podcast_tutorial/Render7-Podcast-Tutorial.png differ diff --git a/source/_static/images/import_documentation/podcast_tutorial/Render8-Podcast-Tutorial.png b/source/_static/images/import_documentation/podcast_tutorial/Render8-Podcast-Tutorial.png new file mode 100644 index 0000000000000000000000000000000000000000..6dc4d09c4aa99dffddb478634d5abe3912ff7ab3 Binary files /dev/null and b/source/_static/images/import_documentation/podcast_tutorial/Render8-Podcast-Tutorial.png differ diff --git a/source/_static/images/import_documentation/podcast_tutorial/Render9-Podcast-Tutorial.png b/source/_static/images/import_documentation/podcast_tutorial/Render9-Podcast-Tutorial.png new file mode 100644 index 0000000000000000000000000000000000000000..be456e7e694a4bd8270229cca6ade0c3a19e6a0b Binary files /dev/null and b/source/_static/images/import_documentation/podcast_tutorial/Render9-Podcast-Tutorial.png differ diff --git a/source/import_documentation/Mixins/widget-mixin.rst b/source/import_documentation/Mixins/widget-mixin.rst index 9593647672fbc0f6114dd92d9c1ba0e3a0bf42a2..1f0d745ccb47acebe2e2525ecf6790b5feddce53 100644 --- a/source/import_documentation/Mixins/widget-mixin.rst +++ b/source/import_documentation/Mixins/widget-mixin.rst @@ -192,8 +192,7 @@ Attributes It can be used in : - - ``solid-display``: a nested ``solid-display`` will be created with the container URI as - data-src. + - ``solid-display``: a nested ``solid-display`` will be created with the container URI as data-src. All attributes of the form ``multiple-[field]-[attribute]`` are transfered on the nested ``solid-display`` as ``[attribute]``. For example, to choose the fields you want to display, you can set: diff --git a/source/import_documentation/build-full-application.rst b/source/import_documentation/build-full-application.rst index 8b5fb1bbd0e390ea6ea7f43cdf5bf007e3312d01..fb6abf6f5f33f35e25c2233c7c822f225b934bb4 100644 --- a/source/import_documentation/build-full-application.rst +++ b/source/import_documentation/build-full-application.rst @@ -8,7 +8,8 @@ With the core of the framework and some offical components, we'll be able to bui To start, simply import the core in your HTML file: -.. code:: html +.. code-block:: html + <!-- ... Import the core ... --> <script type="module" src="https://unpkg.com/@startinblox/core"></script> </head> @@ -21,7 +22,8 @@ You can now freely use all the component included in the core. For the example we are going to build a directory. -.. code:: html +.. code-block:: html + <!-- ... Add a form ... --> <sib-form data-src="https://api.startinblox.com/users/" @@ -49,7 +51,8 @@ The form and the display are connected to the same data sources. When you add pe Let's assume we want to add a menu to our app. We're gonna add the router component ``sib-router`` -.. code:: html +.. code-block:: html + <!-- ... Import the core ... --> <script type="module" src="https://unpkg.com/@startinblox/core"></script> <!-- ... Import SiB Router ... --> diff --git a/source/import_documentation/djangoldp-references.rst b/source/import_documentation/djangoldp-references.rst index cf577ad9751ca268d92389882c732d4483331acc..ea4787495626f29033ac1448e723a8891d19eefe 100644 --- a/source/import_documentation/djangoldp-references.rst +++ b/source/import_documentation/djangoldp-references.rst @@ -4,7 +4,8 @@ DjangoLDP reference guide The DjangoLDP commands ====================== -.. code-block:: bash +.. code-block:: bash + $ djangoldp --help Usage: djangoldp [OPTIONS] COMMAND [ARGS]... @@ -21,7 +22,7 @@ The DjangoLDP commands runserver Run the Django embeded webserver. startpackage Start a DjangoLDP package. -The `djangoldp` server is built ontop of `django` framework. The `django` core commands are also available. Check `python manage.py --help` and [the official Django documentation](https://docs.djangoproject.com/en/2.2/) +The `djangoldp` server is built ontop of `django` framework. The `django` core commands are also available. Check `python manage.py --help` and `the official Django documentation <https://docs.djangoproject.com/en/2.2/>`__. The Initserver command ---------------------- @@ -117,15 +118,15 @@ The DjangoLDP packages capabilities Among other things, the package has a special file allowing a package to load settings when the djangoldp server starts. The `djangoldp_settings.py` file can reference custom variables and load extra middlewares (they are added to the ones loaded by the djangoldp server itself). -``` -# cat mypkg/mypkg/djangoldp_settings.py -MIDDLEWARE = [] -MYPACKAGE_VAR = 'MY_DEFAULT_VAR' -``` +.. code-block:: python + + # cat mypkg/mypkg/djangoldp_settings.py + MIDDLEWARE = [] + MYPACKAGE_VAR = 'MY_DEFAULT_VAR' As any other packages, local packages needs to be referenced in the project `settings.yml`: -``` -ldppackages: - - mypkg -``` +.. code-block:: yml + + ldppackages: + - mypkg diff --git a/source/import_documentation/faq.rst b/source/import_documentation/faq.rst index 44b6987913822b013e97c345f8d903fedf69013b..6237d2875dd73151905c7405fb84373f9bd355a0 100644 --- a/source/import_documentation/faq.rst +++ b/source/import_documentation/faq.rst @@ -27,7 +27,7 @@ We're working to make some popularizations for differents audiences. In the mean The whole project is under `MIT licence <https://git.startinblox.com/framework/sib-core/blob/master/LICENSE/>`__. -* **Why the documentation is not in makdown?** +* **Why the documentation is not in markdown?** This documentation in is `Restructured Text <https://docutils.sourceforge.io/rst.html>`__. `Have a look to this article <https://www.ericholscher.com/blog/2016/mar/15/dont-use-markdown-for-technical-docs/>`__ if you want to understand our choice. diff --git a/source/import_documentation/install-djangoldp-server.rst b/source/import_documentation/install-djangoldp-server.rst index 0c22d268f068fdd32310a876f954b3e3cad981d2..d7e0335f403e9475be1a3181eab6bb6b5b89911c 100644 --- a/source/import_documentation/install-djangoldp-server.rst +++ b/source/import_documentation/install-djangoldp-server.rst @@ -7,7 +7,7 @@ Our solution is based on `Django <https://www.djangoproject.com/>`__ and named ` Go to `Server Architecture <server-architecture.html>`_ to know more about it. -And check the `References guide <djangoldp_references.html>`__ to know all the details. +And check the `References guide <djangoldp-references.html>`__ to know all the details. Requirements ============ diff --git a/source/import_documentation/introduction-framework-documentation.rst b/source/import_documentation/introduction-framework-documentation.rst index 66cc1d70ae7611764983d3ecf265491165bc4821..2bda150a15bbec67f5a6e1a8c55957009574249d 100644 --- a/source/import_documentation/introduction-framework-documentation.rst +++ b/source/import_documentation/introduction-framework-documentation.rst @@ -4,6 +4,7 @@ Introduction of the framework documentation In the following sections, the framework's components are detailed. **Base components** belong to the core of the framework. + For each component, you will find: * a minimal example of usage (and related examples), * a list of mixins used by the component, diff --git a/source/import_documentation/tutorial-podcast.rst b/source/import_documentation/tutorial-podcast.rst new file mode 100644 index 0000000000000000000000000000000000000000..b3bd9bab07fe29d662b1012db6defed873c2a3ea --- /dev/null +++ b/source/import_documentation/tutorial-podcast.rst @@ -0,0 +1,347 @@ +Startin'blox Podcast Tutorial +############################# + +Presentation and Objectives +=========================== + +Startin'blox provides SOLID components called "blox" to build-up a website or a webapp that can consume and +manage data from various SOLID-compatible sources. This tutorial shows the various front-end blox available +in the framework and describe step-by-step how to use it to make a podcast reader and sharing application. +This application is build as a blox itself and can be embeded in a website by just dropping a +``<solid-podcast>`` tag in the page. + +Here is the simple mockup that shows what the component will look like : + +.. figure:: ../../_static/images/import_documentation/podcast_tutorial/Mockup-Podcast-Tutorial.png + :alt: Mockup Podcast + +In this tutorial, we will use some `Radio France podcasts <https://www.franceinter.fr/podcasts-originaux>`__. +Feel free to use your own if you like. + + +Teaching Objectives +------------------- + +* Learn what a data source is +* Use ``solid-display`` blox and understand the basic concepts about the consumed data +* Organise the listed items and use widgets to customize the display (fields, field sets, img, ...) +* Apply css to have your own look-and-feel +* Create custom widgets +* Plug js to have your own behavior + + +Semantic data source +==================== + +Before begining our journey, we need a semantic data source formatted in a way that the framework can +understand. The only supported format today in Startin'blox JSON Linked Data (`JSON-LD <https://json-ld.org/>`__). + +But a vast majority of podcast feeds are provided in RSS format. So let's use a simple conversion tool +that will take a podcast RSS feed and format it to JSON-LD. You can find this little helper called +``rss2jsonld`` on `this git repository <https://git.startinblox.com/fabien4vo/rss2jsonld/>`__ or use directly the +bundled source from https://cdn.startinblox.com/tuto/rss2jsonld.js. + + +Setup the environment and display data +====================================== + +To use the Startin'blox framework, just embed it in the head of your html : + +.. code-block:: html + + <!DOCTYPE html> + <html> + <head> + <meta charset="utf-8"/> + <title>SiB tutorial - Podcast</title> + <script type="module" src="https://cdn.skypack.dev/@startinblox/core@0.15"></script> + <script src="https://cdn.startinblox.com/tuto/rss2jsonld.js"></script> + </head> + <body> + </body> + </html> + +``core`` is the "heart" of the framework, and contains all the needed parts to get started. The current version +of the core is ``0.15.6`` at the time of writing. The third number will increase with each published improvement +and bugfix. Using ``@0.15`` at the end of the url will make it point to the latest bugfix available. The second +number ``15`` will increase when new feature or breaking change are introduced. If you remove the @15 from the +url, your application will get the next release as soon as it is published, but you probably have to change some +part of it to make it work with this new version. So specifying the version is safer. + +The ``rss2jsonld`` script is here to automatically convert RSS data source to JSON-LD format. + +We can now use our first blox : ``<solid-display>``. Startin'blox use the `HTML Custom Element specification <https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements>`__ +which is part of the webcomponents standard, to create those blox. So you can use it as any other HTML tag, +like ``<video>`` or ``<select>``. This blox simply displays the data provided by the linked data source : + +.. code-block:: html + + <solid-display data-src="http://radiofrance-podcast.net/podcast09/rss_20856.xml" no-render/> + +I use the ``no-render`` attribute so that the RSS XML feed is not loaded by startin'blox until it was converted +by ``rss2jsonld``. + +The result is not very pretty : all fields are displayed in plain text without formatting : + +.. figure:: ../../_static/images/import_documentation/podcast_tutorial/Render1-Podcast-Tutorial.png + :alt: Data displayed without formatting + + +Organize and format data +======================== + +To put data in order, we use the ``fields`` tag : + +.. code-block:: html + + <solid-display + data-src="http://radiofrance-podcast.net/podcast09/rss_20856.xml" + no-render + fields="title, description" + /> + +``fields`` take an ordered list of field names (found in the data source) and make the component to display only those fields in the provided order. + +We can also use a **widget** to specify how each field must be shown : + +.. code-block:: html + + <solid-display + data-src="http://radiofrance-podcast.net/podcast09/rss_20856.xml" + fields="title, description" + widget-title="h1" + no-render + /> + +``widget-[field]`` take a HTML tag name and make the component use it to display this field. + +.. figure:: ../../_static/images/import_documentation/podcast_tutorial/Render2-Podcast-Tutorial.png + :alt: Data displayed with H1 + +It starts to look better ! + +Any HTML element can be used as widget, but Startin'blox also provide **built-in widgets** to easily manage specific +cases. To display images from their url, use the ``solid-display-img`` widget : + +.. code-block:: html + + <solid-display + data-src="http://radiofrance-podcast.net/podcast09/rss_20856.xml" + fields="title, image.url, description" + widget-title="h1" + widget-image.url="solid-display-img" + no-render + /> + +Fields can also be grouped in **sets** using brackets : each bracket opens or closes a group, and groups can be +nested. The word before the opening bracket is the group name and can be used to have a specific widget to display this group. + +.. code-block:: html + + <solid-display + data-src="http://radiofrance-podcast.net/podcast09/rss_20856.xml" + fields="title, image.url, meta(itunes:author, itunes:category.text), description" + widget-title="h1" + widget-image.url="solid-display-img" + widget-meta="p" + no-render + /> + +.. figure:: ../../_static/images/import_documentation/podcast_tutorial/Render3-Podcast-Tutorial.png + :alt: Data displayed with image + + +Apply CSS to have your own look-and-feel +======================================== + +``solid-display`` uses standard HTML to display the data, and that HTML can be styled with CSS. + +.. code-block:: html + + <style> + solid-display { + max-width: 800px; + display: block; + margin: auto; + } + solid-display img { + width: 200px; + float: left; + margin-right: 20px; + } + </style> + +.. figure:: ../../_static/images/import_documentation/podcast_tutorial/Render4-Podcast-Tutorial.png + :alt: Data displayed, CSS added + + +You can also target specific field with an attribute selector because ``<solid-display>`` component adds a +``name="[field]"`` attribute to the displayed data. + +.. code-block:: html + + [name="itunes:category.text"]{ + display: inline-block; + border: solid thin; + padding: 0.2em 0.5em; + margin: 0 1em; + border-radius: 0.5em; + } + +.. figure:: ../../_static/images/import_documentation/podcast_tutorial/Render5-Podcast-Tutorial.png + :alt: Data displayed, CSS added next + + +But sometimes it's easier and cleaner to use classes. ``class-[field]`` tags let's you specify a class name. + +.. code-block:: html + + <style> + .bordered { + display: inline-block; + border: solid thin; + padding: 0.2em 0.5em; + margin: 0 1em; + border-radius: 0.5em; + } + </style> + + <solid-display + data-src="http://radiofrance-podcast.net/podcast09/rss_20856.xml" + fields="title, image.url, meta(itunes:author, itunes:category.text), description" + widget-title="h1" + widget-image.url="solid-display-img" + widget-meta="p" + class-itunes:category.text="bordered" + no-render + /> + +You can also use arbitrary text (enclosed by single quotes) in the fields list to display a text node : + +.. code-block:: html + + <solid-display + data-src="http://radiofrance-podcast.net/podcast09/rss_20856.xml" + fields="title, image.url, meta('By: ', itunes:author, itunes:category.text), description" + [...] + /> + +.. figure:: ../../_static/images/import_documentation/podcast_tutorial/Render6-Podcast-Tutorial.png + :alt: Data displayed, CSS and text enclosed by sigle quotes + + +Display nested list fields +========================== + +Let's now display the informations about podcast episodes. They are listed in the ``item`` field, and as soon as it's +a list we have to tell the framework that it should be treated as multiple values. + +This is achieved with the ``multiple-[field]`` attributes. This tag creates a nested ``<solid-display>`` for each entry in +``item``. ``multiple-[field]-fields`` attribute is used to control which nested fields are displayed for each item. + +.. code-block:: html + + <solid-display + data-src="http://radiofrance-podcast.net/podcast09/rss_20856.xml" + fields="title, header(image.url, info( meta('By: ', itunes:author, itunes:category.text), description)), item" + widget-title="h1" + widget-image.url="solid-display-img" + widget-meta="p" + class-itunes:category.text="bordered" + widget-header="header" + multiple-item + multiple-item-fields="title" + no-render + /> + +.. figure:: ../../_static/images/import_documentation/podcast_tutorial/Render7-Podcast-Tutorial.png + :alt: Add item in data displayed + + +Custom template +=============== + +To go further, we need to create our own widget template using the ``solid-widget`` tag. Let's show other episode data: + +.. code-block:: html + + <solid-widget name="podcast-episode"> + <template> + <solid-display + data-src="${value}" + fields="title, meta(pubDate, itunes:duration), description" + widget-title="h2" + widget-description="p" + /> + </template> + </solid-widget> + + <solid-display + data-src="http://radiofrance-podcast.net/podcast09/rss_20856.xml" + [...] + multiple-item="podcast-episode" + no render + /> + +``solid-widget`` tag must be used with ``template`` to avoid its content to be rendered during the first page display. +The code included in the template is then used by Startin'blox to render each item. And you can use here again all the +attributes we juste learned, such as ``fields`` and ``widget-[field]``. + +.. figure:: ../../_static/images/import_documentation/podcast_tutorial/Render8-Podcast-Tutorial.png + :alt: Add custom template for item + + +Plug a bit of Javascript +======================== + +When a custom widget template is used, it gets a javascript variable called ``value`` that contains the resource. It can be +displayed directly in the template using ``${value}`` or you can apply some Javascript to it before. For example, here is how +to format the date using the browser locale settings : + +.. code-block:: html + + <solid-widget name="format-date"> + <template> + <time datetime="${value}">${new Date(value).toLocaleDateString(undefined, {weekday: 'long', year: 'numeric', month: 'long', day: 'numeric'})}</time> + </template> + </solid-widget> + +Now if I use ``widget-pubDate="format-date"`` in ``<solid-widget name="podcast-episode">``, I get a nice formatted date : + +.. figure:: ../../_static/images/import_documentation/podcast_tutorial/Render9-Podcast-Tutorial.png + :alt: Plug JS in a solid-widget + +And this template mechanism plays also nicely with other HTML5 standard tags, such as ``audio`` : + +.. code-block:: html + + <solid-widget name="audio-player"> + <template> + <audio src="${value}" controls/> + </template> + </solid-widget> + + <solid-widget name="podcast-episode"> + <template> + <solid-display + data-src="${value}" + fields="title, meta('Épisode du ', pubDate, ' - ', itunes:duration), description, enclosure.url" + widget-title="h2" + widget-description="p" + widget-pubDate="format-date" + widget-enclosure.url="audio-player" + /> + </template> + </solid-widget> + +.. figure:: ../../_static/images/import_documentation/podcast_tutorial/Render10-Podcast-Tutorial.png + :alt: Add audio player solid-widget + + +Conclusion +========== + +This short tutorial has showed how to display the data from a podcast RSS feed using startin'blox framework. You can now +check this is working with other podcasts (provided that CORS headers are set on the server). + +You can find the code on `this repository <https://git.startinblox.com/fabien4vo/solid-podcast>`__. \ No newline at end of file diff --git a/source/index.rst b/source/index.rst index 153bce23dfde11d47595afa12f378ef88bc38eda..73bb06d71d61b46fcc7579f7cb9ab005ac1d9dc5 100644 --- a/source/index.rst +++ b/source/index.rst @@ -26,6 +26,7 @@ Welcome to Startinblox's documentation :caption: Get started with sib-core import_documentation/introduction-framework-documentation + import_documentation/tutorial-podcast import_documentation/attributes-list .. toctree::