From 1e78ad4828a05a5dbd54a230fc743ff6f18354a1 Mon Sep 17 00:00:00 2001 From: FUN MOOC Bot Date: Wed, 17 Apr 2024 14:59:44 +0000 Subject: [PATCH] Deploy website - based on 3d1f47110e54222d07967c639fb182d54ab9fd0e --- 404.html | 8 ++++---- .../css/{styles.bc5d7c07.css => styles.c29f85f3.css} | 2 +- assets/js/000b5b65.7843b4ce.js | 1 + assets/js/000b5b65.b1fe522f.js | 1 - assets/js/00936db6.43128f3e.js | 1 - assets/js/00936db6.fa95273e.js | 1 + assets/js/00a73d6c.1fe4d188.js | 1 + assets/js/00a73d6c.dbe2ecca.js | 1 - assets/js/0282d9da.39cf5b70.js | 1 + assets/js/0282d9da.8043f81c.js | 1 - .../{2f1db623.d8badd5c.js => 0293ad88.eb8399b8.js} | 2 +- assets/js/0293ad88.fff4af89.js | 1 - assets/js/02a6e85d.d4fafaee.js | 1 + assets/js/02a6e85d.d7aeadaa.js | 1 - assets/js/02aff391.0126c97b.js | 1 + assets/js/02aff391.34c4176e.js | 1 - assets/js/02fbc50f.06a2e257.js | 1 - assets/js/02fbc50f.9f114b36.js | 1 + assets/js/0386b2c0.26f5414a.js | 1 - assets/js/0386b2c0.49fc2b6a.js | 1 + assets/js/03a6f5b2.92d59349.js | 1 + assets/js/03a6f5b2.e2306470.js | 1 - assets/js/03e22855.0b6f1028.js | 1 + assets/js/03e22855.5db721db.js | 1 - assets/js/03e479ab.13f98885.js | 1 + assets/js/03e479ab.c258e004.js | 1 - assets/js/05054f56.65f6d618.js | 1 - assets/js/05054f56.79ea3f6b.js | 1 + assets/js/05adccc0.3f338ef6.js | 1 + assets/js/05adccc0.f2de587c.js | 1 - assets/js/061b9ec0.8578e0c1.js | 1 - assets/js/061b9ec0.bba32130.js | 1 + assets/js/06447dd5.3f895c02.js | 1 - assets/js/06447dd5.6cf6e11d.js | 1 + assets/js/06bcdf26.1d5f8354.js | 1 + assets/js/06bcdf26.d190b60e.js | 1 - assets/js/06e6648e.0cbd1b43.js | 1 - assets/js/06e6648e.52069984.js | 1 + assets/js/07ba485a.5951a251.js | 1 - assets/js/07ba485a.ff70a59c.js | 1 + assets/js/07dcad66.3f781cbb.js | 1 - assets/js/07dcad66.ddf2d91a.js | 1 + assets/js/07f167f3.3765bd72.js | 1 + assets/js/07f167f3.970290a6.js | 1 - assets/js/08cf9976.47182207.js | 1 + assets/js/08cf9976.9f4d3dff.js | 1 - assets/js/08d8a2f4.5d27a0f5.js | 1 - assets/js/08d8a2f4.6abb478b.js | 1 + assets/js/096f38f4.5e79698a.js | 1 + assets/js/096f38f4.a5315ca4.js | 1 - assets/js/097ac4c7.9fa3e729.js | 1 - assets/js/097ac4c7.addccb10.js | 1 + assets/js/0994b750.25a6e89e.js | 1 - assets/js/0994b750.47049489.js | 1 + assets/js/099fd313.a308f218.js | 1 - assets/js/099fd313.c99f6cff.js | 1 + assets/js/09dbdf3a.2f79efdb.js | 1 + assets/js/09dbdf3a.677e47cf.js | 1 - assets/js/09f8bc84.281c6ff0.js | 1 - assets/js/09f8bc84.c97c3b99.js | 1 + assets/js/09fcd96a.76580d58.js | 1 + assets/js/09fcd96a.a3e897b9.js | 1 - assets/js/0add6094.6e6ebca3.js | 1 - assets/js/0add6094.faffc24e.js | 1 + assets/js/0ae680de.25a0920e.js | 1 + assets/js/0b14c283.2dadbf41.js | 1 + assets/js/0b14c283.7de4cdaa.js | 1 - assets/js/0b704f48.125b280b.js | 1 - assets/js/0b704f48.9d9cb121.js | 1 + assets/js/0b7302f4.ab68a346.js | 1 - assets/js/0b7302f4.d7b06e14.js | 1 + assets/js/0c537762.9ae5486a.js | 1 + assets/js/0c537762.abc38d88.js | 1 - assets/js/0c6c321c.ebc66fa9.js | 1 - assets/js/0c6c321c.ff7c58ea.js | 1 + assets/js/0ce075bd.6e1439e3.js | 1 - assets/js/0ce075bd.6eabb8db.js | 1 + assets/js/0d621e61.d46e5536.js | 1 + assets/js/0d621e61.ef268db2.js | 1 - assets/js/0db3065d.7cbbe3b3.js | 1 - assets/js/0db3065d.f1417ff0.js | 1 + assets/js/0e19e8fc.7946f3b9.js | 1 + assets/js/0e19e8fc.fe814962.js | 1 - assets/js/0e83f9e9.d9927db6.js | 1 + assets/js/0e83f9e9.eda23db6.js | 1 - assets/js/0ea4a466.92361403.js | 1 + assets/js/0ea4a466.dcc084d5.js | 1 - assets/js/0f3a7c54.c55c081e.js | 1 + assets/js/0f3a7c54.cc630390.js | 1 - assets/js/0f431cec.da780187.js | 1 + assets/js/0f431cec.eef7aad1.js | 1 - assets/js/0f6d1c6c.bff09f92.js | 1 - assets/js/0f6d1c6c.f0e1a802.js | 1 + assets/js/0fc2919f.5e5ec8a4.js | 1 - assets/js/0fc2919f.73dfb141.js | 1 + assets/js/103b72cd.88c8709c.js | 1 + assets/js/103b72cd.ba57cf7c.js | 1 - assets/js/1050eb4f.2e6d816c.js | 1 + assets/js/1050eb4f.a140a676.js | 1 - assets/js/1053756e.75139f1c.js | 1 - assets/js/1053756e.91d50c35.js | 1 + assets/js/10a40cfc.16b7773d.js | 1 + assets/js/10a40cfc.75486736.js | 1 - assets/js/10fdb3ce.90ecd733.js | 1 - assets/js/10fdb3ce.b20e20e9.js | 1 + assets/js/112db83c.3771fe56.js | 1 - .../{4acc282a.4a69cad6.js => 112db83c.64e15de5.js} | 2 +- assets/js/11415922.a91a1311.js | 1 + assets/js/11f70aa8.810e75ee.js | 1 + assets/js/11f70aa8.af41768c.js | 1 - assets/js/127c2ea3.f1d5f84d.js | 1 - assets/js/127c2ea3.f35d79f7.js | 1 + assets/js/127f66d4.90a8f98f.js | 1 + assets/js/127f66d4.a26d6c91.js | 1 - assets/js/136c1d54.6df5d49f.js | 1 + assets/js/136c1d54.a72b4a9d.js | 1 - assets/js/13c51ea3.0c46cb2d.js | 1 - assets/js/13c51ea3.18e83337.js | 1 + assets/js/13f7722f.83195828.js | 1 - assets/js/13f7722f.88286c29.js | 1 + .../{3e42226b.eb8e97ad.js => 14e5e79f.3e19f51d.js} | 2 +- assets/js/14e5e79f.ed07131b.js | 1 - assets/js/14f618b0.8a8e5aa6.js | 1 + assets/js/14f618b0.c078db23.js | 1 - assets/js/15106207.77740055.js | 1 + assets/js/15106207.8221626e.js | 1 - assets/js/164a50fb.0b4e2a86.js | 1 + assets/js/164a50fb.f976d84a.js | 1 - assets/js/1681c897.7e1771c5.js | 1 + assets/js/1681c897.e909a8c7.js | 1 - assets/js/168235c0.1ddb7c5e.js | 1 + assets/js/168235c0.d25627ce.js | 1 - assets/js/171addfa.1b9e2c9a.js | 1 + assets/js/171addfa.9b35e9b5.js | 1 - assets/js/172cef5d.5880b1be.js | 1 + assets/js/17896441.028fad21.js | 1 - assets/js/17896441.0f4ea831.js | 1 + assets/js/17fa148f.00d8e94c.js | 1 + assets/js/17fa148f.079939ef.js | 1 - assets/js/1818bfeb.597d9670.js | 1 - assets/js/1818bfeb.8d4ee9ef.js | 1 + assets/js/187597a1.7c33e5f0.js | 1 - assets/js/187597a1.c3085446.js | 1 + assets/js/18c55237.69ecc1d4.js | 1 + assets/js/18c55237.f3ae7594.js | 1 - assets/js/18c7e6dd.22c58d97.js | 1 - .../{e23da508.a0c4ef40.js => 18c7e6dd.7f6cc03c.js} | 2 +- assets/js/18ec690c.0560c7b4.js | 1 + assets/js/18ec690c.0f6d7606.js | 1 - assets/js/19030215.8396b107.js | 1 - assets/js/19030215.c4a9fa62.js | 1 + assets/js/19099ebb.a71d3901.js | 1 + assets/js/1988e61b.02de9c41.js | 1 - assets/js/1988e61b.f83c3fa6.js | 1 + assets/js/19b30c77.62741dd6.js | 1 + assets/js/19b30c77.e4ff61dc.js | 1 - assets/js/1b0422f0.5d47abb3.js | 1 - assets/js/1b0422f0.73ddfa1e.js | 1 + assets/js/1b22849d.ee9c7835.js | 1 + assets/js/1b22849d.f753b463.js | 1 - assets/js/1b340b9f.07dee382.js | 1 - assets/js/1b340b9f.6f53b7b0.js | 1 + assets/js/1c5e7615.6ed4e74e.js | 1 + assets/js/1c5e7615.ba9f8011.js | 1 - assets/js/1caa6db9.49cd54a0.js | 1 - assets/js/1caa6db9.f77932b6.js | 1 + assets/js/1cf6e8ef.610fab07.js | 1 - assets/js/1cf6e8ef.7857b656.js | 1 + assets/js/1d06aaab.a00fbe8a.js | 1 - assets/js/1d06aaab.f2f8d4cb.js | 1 + assets/js/1d2426fc.77fd1c1a.js | 1 + assets/js/1da01b0f.a3946776.js | 1 + assets/js/1da01b0f.d0f66a71.js | 1 - assets/js/1daa9480.13b40286.js | 1 + assets/js/1daa9480.d5dc103e.js | 1 - assets/js/1dd9b9f1.786aa2ae.js | 1 - assets/js/1dd9b9f1.7f5e74dd.js | 1 + assets/js/1e1fe148.0b9a59ca.js | 1 + assets/js/1e1fe148.af671901.js | 1 - assets/js/1e33be1c.3bf4c671.js | 1 - assets/js/1e33be1c.e869702f.js | 1 + assets/js/1e38d8f6.3c21f419.js | 1 + assets/js/1e38d8f6.cc18e34d.js | 1 - assets/js/1f7fcbb7.14eb1f4b.js | 1 - assets/js/1f7fcbb7.2a0c5483.js | 1 + assets/js/1f910db0.3a2c8f08.js | 1 + assets/js/1f910db0.5553b1bb.js | 1 - assets/js/1fafbf27.424ebb48.js | 1 + assets/js/1fafbf27.cefabd30.js | 1 - assets/js/2016fde8.47e7a98f.js | 1 + assets/js/2016fde8.63fd4761.js | 1 - assets/js/201fa7d6.0a7f64e9.js | 1 + assets/js/201fa7d6.eacf7af9.js | 1 - assets/js/20375412.6753cf29.js | 1 - assets/js/20375412.c180f4ea.js | 1 + assets/js/208b3683.2def0e96.js | 1 + assets/js/208b3683.624000eb.js | 1 - assets/js/209f9d96.2908ee72.js | 1 - assets/js/209f9d96.62e294db.js | 1 + assets/js/20c8a971.5a979e77.js | 1 + assets/js/20c9ae5c.65d32fde.js | 1 + assets/js/20c9ae5c.80c18adf.js | 1 - assets/js/20de91ac.11599b79.js | 1 + assets/js/20de91ac.34992e2c.js | 1 - assets/js/20ded4b9.d5eec564.js | 1 + assets/js/20ded4b9.df5646e2.js | 1 - assets/js/20e1c70d.41277a89.js | 1 + assets/js/20e1c70d.7c864bdb.js | 1 - assets/js/211a457e.8d860d98.js | 1 + assets/js/211a457e.e9b01723.js | 1 - assets/js/216f1911.9fa91641.js | 1 + assets/js/216f1911.bbb2e1ad.js | 1 - assets/js/225aacf5.90345b3c.js | 1 + assets/js/225aacf5.f9938e43.js | 1 - assets/js/23012ccd.44d6744b.js | 1 + assets/js/23012ccd.e0afde49.js | 1 - assets/js/238b593d.282969ff.js | 1 - assets/js/238b593d.aa15f2ae.js | 1 + assets/js/2392e8d5.8ae29191.js | 1 - assets/js/2392e8d5.def65ee5.js | 1 + assets/js/23f4de98.821bb624.js | 1 - assets/js/23f4de98.90a0206d.js | 1 + assets/js/2411f77f.3baf3d1c.js | 1 - assets/js/2411f77f.48eb3be1.js | 1 + assets/js/24ce56fa.67a170e3.js | 1 + assets/js/24ce56fa.e7322eac.js | 1 - assets/js/251cb658.7ce61fc7.js | 1 + assets/js/251cb658.d92a4e3d.js | 1 - assets/js/254587dc.57d98d87.js | 1 + assets/js/254587dc.96f96f5e.js | 1 - .../{27cd943b.7f7595dd.js => 254ad699.18617fab.js} | 2 +- assets/js/254ad699.c25fb9d8.js | 1 - assets/js/254f523d.014e2d34.js | 1 - assets/js/254f523d.81f275bd.js | 1 + .../{447f82ad.fee22db6.js => 2682d1a6.3ac7e4cd.js} | 2 +- assets/js/2682d1a6.90f87f09.js | 1 - assets/js/26e576cc.2eb9e86d.js | 1 - assets/js/26e576cc.65415403.js | 1 + assets/js/27461c5b.450d7bd7.js | 1 + assets/js/27461c5b.eb9e2dbe.js | 1 - assets/js/276b156f.a8424219.js | 1 + assets/js/276b156f.d48b2f25.js | 1 - assets/js/278477af.7dc9f137.js | 1 - assets/js/278477af.b40dfc54.js | 1 + assets/js/27cd943b.4c8bd45e.js | 1 + assets/js/28a7aef2.084954d3.js | 1 + assets/js/28a7aef2.b30c88c9.js | 1 - assets/js/291741fc.6e588acd.js | 1 + assets/js/291741fc.b843fa86.js | 1 - assets/js/2945dbfd.740d5eb6.js | 1 + assets/js/2945dbfd.ae8724cc.js | 1 - assets/js/29a15cf5.35132d84.js | 1 + assets/js/29a15cf5.3a254310.js | 1 - assets/js/2aab0461.05ce33cc.js | 1 - assets/js/2aab0461.c4a3bef0.js | 1 + assets/js/2ad723ae.8e1ba04e.js | 1 + assets/js/2ad723ae.b52b6f66.js | 1 - assets/js/2b0294df.250dd975.js | 1 + assets/js/2b0294df.c8312699.js | 1 - assets/js/2b0ea6a3.08a711c0.js | 1 - assets/js/2b0ea6a3.3f2c6d1a.js | 1 + assets/js/2b603511.15ddc564.js | 1 - assets/js/2b603511.6de69622.js | 1 + assets/js/2bd76b34.8e151178.js | 1 + assets/js/2bd76b34.adb22582.js | 1 - assets/js/2c72f107.5252ca4b.js | 1 + assets/js/2c72f107.54cab9b5.js | 1 - assets/js/2cb39df3.4ed9fa33.js | 1 - assets/js/2cb39df3.67ccf65d.js | 1 + assets/js/2cc95c91.70439a41.js | 1 + assets/js/2cc95c91.72cfe0e4.js | 1 - assets/js/2ccae19e.160f0b50.js | 1 + assets/js/2ccae19e.86a37cfb.js | 1 - assets/js/2dc75d44.c2124428.js | 1 + assets/js/2dc75d44.f1d7f5bf.js | 1 - assets/js/2dd5feb9.5b7178d3.js | 1 + assets/js/2dd5feb9.b3750dc3.js | 1 - assets/js/2eb4cc07.528ce82b.js | 1 + assets/js/2eb4cc07.877a2862.js | 1 - assets/js/2ef36261.bacf5085.js | 1 - assets/js/2ef36261.ef722f7c.js | 1 + assets/js/2f1db623.37c4382f.js | 1 + assets/js/2f83db41.31d0c7fb.js | 1 + assets/js/2f83db41.c4367721.js | 1 - assets/js/2fbb3042.752272f6.js | 1 + assets/js/2fbb3042.cc7c252a.js | 1 - assets/js/2fbc32c8.4330ee46.js | 1 + assets/js/2fbc32c8.b23a92de.js | 1 - assets/js/30bcdfaf.093e7389.js | 1 - assets/js/30bcdfaf.9007471e.js | 1 + assets/js/30d29c5d.42d64433.js | 1 + assets/js/30d29c5d.933b5d75.js | 1 - assets/js/312a9924.3b800466.js | 1 + assets/js/312a9924.56934f0d.js | 1 - assets/js/32315083.8fd79ff1.js | 1 + assets/js/32315083.bf371d37.js | 1 - assets/js/32488265.47522df2.js | 1 + assets/js/32488265.c592ff30.js | 1 - assets/js/325a4da8.01193e3d.js | 1 - assets/js/325a4da8.8ce42c11.js | 1 + assets/js/32c602fd.7dc7c8cf.js | 1 - assets/js/32c602fd.e29557bd.js | 1 + assets/js/3311796b.41d66a37.js | 1 - assets/js/3311796b.8670fdd2.js | 1 + assets/js/335c1f05.274bb590.js | 1 - .../{74dddc49.4d3bcba9.js => 335c1f05.a5ed56b4.js} | 2 +- assets/js/33fbc32e.0a81c394.js | 1 + assets/js/33fbc32e.61332f9e.js | 1 - assets/js/34596675.54a193b0.js | 1 - assets/js/34596675.8c0b03b6.js | 1 + assets/js/34cb51de.a90aec9a.js | 1 + assets/js/34ff41bb.631eaacf.js | 1 - assets/js/34ff41bb.7612486d.js | 1 + assets/js/3545c428.130960b0.js | 1 - assets/js/3545c428.7c9974af.js | 1 + assets/js/354f5663.17c92ee4.js | 1 - assets/js/354f5663.515bf474.js | 1 + assets/js/3585f5da.4f4d7a3c.js | 1 + assets/js/3585f5da.73d01c44.js | 1 - assets/js/3673a8ce.6c8697ed.js | 1 + assets/js/3673a8ce.ba714810.js | 1 - assets/js/3714cfae.c7932a1d.js | 1 + assets/js/3714cfae.d0c80244.js | 1 - assets/js/371d0026.f3fbf9d1.js | 1 - .../{172cef5d.57ad0a39.js => 371d0026.f87223a6.js} | 2 +- assets/js/37273ca3.04fe3a3e.js | 1 + assets/js/37273ca3.dc3d1494.js | 1 - assets/js/378ee88a.05959ca7.js | 1 - assets/js/378ee88a.ad22836b.js | 1 + assets/js/384badf6.9548c9f1.js | 1 - assets/js/384badf6.ca991f6d.js | 1 + assets/js/38896deb.1397ea04.js | 1 + assets/js/38896deb.f0a0a117.js | 1 - assets/js/389c8989.039e42c7.js | 1 + assets/js/389c8989.78f3e453.js | 1 - assets/js/38ae1160.526e0b87.js | 1 + assets/js/38ae1160.fa79ecf0.js | 1 - assets/js/38c22082.08365f5d.js | 1 + assets/js/38c22082.91c8c244.js | 1 - assets/js/395eb7c6.5b64e2d5.js | 1 + assets/js/395eb7c6.e05ee302.js | 1 - assets/js/39917643.ae75d537.js | 1 - assets/js/39917643.bf026dd3.js | 1 + assets/js/3a0f357d.3e103301.js | 1 - assets/js/3a0f357d.ddf84d84.js | 1 + assets/js/3a5b4eed.270d442c.js | 1 + assets/js/3a5b4eed.b15911cb.js | 1 - assets/js/3a6bbf33.292b96b4.js | 1 + assets/js/3a6f03ad.51fd014f.js | 1 + assets/js/3a6f03ad.ea386127.js | 1 - assets/js/3b31280e.1952d591.js | 1 + assets/js/3b31280e.37bb291e.js | 1 - assets/js/3bfd137c.a6927c11.js | 1 + assets/js/3bfd137c.e2e73e15.js | 1 - assets/js/3c1a2d15.41f2e362.js | 1 + assets/js/3c1a2d15.f429ea42.js | 1 - assets/js/3c1a997b.1cb76f74.js | 1 + assets/js/3c1a997b.ffdd669f.js | 1 - assets/js/3c775348.67d7740a.js | 1 - assets/js/3c775348.7785e1b0.js | 1 + assets/js/3c7d7aed.9f3ee25b.js | 1 + assets/js/3cc42aff.5ce2bd96.js | 1 + assets/js/3cc42aff.ff0bba56.js | 1 - assets/js/3d1f5df7.81608679.js | 1 - assets/js/3d1f5df7.b6209fa1.js | 1 + assets/js/3dd7b968.567059ea.js | 1 - assets/js/3dd7b968.97caa4d0.js | 1 + assets/js/3de0f5e2.5cba7bde.js | 1 + assets/js/3de0f5e2.8dd961a6.js | 1 - assets/js/3e0d2163.72af2d09.js | 1 + assets/js/3e0d2163.a086c2e2.js | 1 - assets/js/3e42226b.0d4b11eb.js | 1 + assets/js/3ea77f47.431dd660.js | 1 - assets/js/3ea77f47.b017db9c.js | 1 + assets/js/3fcfa83f.51d4027f.js | 1 + assets/js/3fcfa83f.be3cb794.js | 1 - assets/js/3fd0faed.840b983c.js | 1 + assets/js/3fd0faed.c4111eed.js | 1 - assets/js/4220d24c.d4310642.js | 1 + assets/js/4220d24c.f0359c78.js | 1 - assets/js/42e63d8f.9383f492.js | 1 - assets/js/42e63d8f.ea8f897d.js | 1 + assets/js/43dd260b.8e1b24bf.js | 1 + assets/js/43dd260b.d2ce0297.js | 1 - assets/js/442e170d.8613aef2.js | 1 + assets/js/442e170d.c33fb602.js | 1 - assets/js/447f82ad.25ad796b.js | 1 + assets/js/44b658dc.6dd07555.js | 1 + assets/js/44b658dc.fbe037ed.js | 1 - assets/js/451cc400.48b59541.js | 1 - assets/js/451cc400.b5180164.js | 1 + assets/js/4538b3d3.453d6ab4.js | 1 - assets/js/4538b3d3.6f6839c8.js | 1 + assets/js/4567f559.7292cb07.js | 1 + assets/js/4567f559.c6a298c2.js | 1 - assets/js/45a39ade.b6ebef43.js | 1 - assets/js/45a39ade.bf37498b.js | 1 + assets/js/45fa8fc8.3621c2d3.js | 1 + assets/js/45fa8fc8.f4c2f8c5.js | 1 - assets/js/4610903a.85bcd810.js | 1 - assets/js/4610903a.e6aac95c.js | 1 + assets/js/46651703.8f48696d.js | 1 - assets/js/46651703.dada904a.js | 1 + assets/js/46b63591.4cedb57c.js | 1 + assets/js/46b63591.de4b1355.js | 1 - assets/js/47664efc.8bcf8052.js | 1 + assets/js/47664efc.c3c8270e.js | 1 - assets/js/48393576.2e629f0d.js | 1 + assets/js/48393576.bc594b37.js | 1 - assets/js/48b41b21.2c9a1190.js | 1 + assets/js/48b41b21.7cf12bd2.js | 1 - assets/js/491e3748.4ff3e082.js | 1 - assets/js/491e3748.6c0c8dde.js | 1 + assets/js/49a3ff07.1f7f5aaa.js | 1 - assets/js/49a3ff07.711f5883.js | 1 + assets/js/49c1aea8.c1ddc52e.js | 1 - assets/js/49c1aea8.cec05417.js | 1 + assets/js/49c28f3e.7ac4cf71.js | 1 + assets/js/49c28f3e.f868b412.js | 1 - assets/js/49c48079.7b77e0b8.js | 1 - assets/js/49c48079.86b9f69c.js | 1 + assets/js/4a372eea.70759cc3.js | 1 - assets/js/4a372eea.9bb65e5b.js | 1 + assets/js/4a72972d.00279647.js | 1 + assets/js/4a72972d.cae2251e.js | 1 - assets/js/4acc282a.1af063af.js | 1 + assets/js/4b3d2ce7.2e3a4f7d.js | 1 + assets/js/4b3d2ce7.886060b2.js | 1 - assets/js/4bc32079.16d2ed76.js | 1 + assets/js/4bc32079.7158e393.js | 1 - assets/js/4cdff131.e2bf0707.js | 1 - assets/js/4cdff131.e58b7eed.js | 1 + assets/js/4cecff54.a807f016.js | 1 + assets/js/4cecff54.c0dd006c.js | 1 - assets/js/4d48fcb7.7c664edb.js | 1 + assets/js/4d48fcb7.c1246af6.js | 1 - assets/js/4dba59ca.2994a3d8.js | 1 - assets/js/4dba59ca.c9379215.js | 1 + assets/js/4dd6f7af.427f7494.js | 1 - assets/js/4dd6f7af.f2227789.js | 1 + assets/js/4e278954.c7dae782.js | 1 - assets/js/4e278954.d707241f.js | 1 + assets/js/4e8f03cd.507058d0.js | 1 + assets/js/4e8f03cd.c860a615.js | 1 - assets/js/4ea51cf7.11b2de1e.js | 1 + assets/js/4ea51cf7.d495e1f1.js | 1 - assets/js/4ee76bca.f08ac328.js | 1 + assets/js/4f2fd236.ae9aaff4.js | 1 + assets/js/4f2fd236.e40e2d57.js | 1 - assets/js/4f59363e.88fef57d.js | 1 - assets/js/4f59363e.ab5bc414.js | 1 + assets/js/4feb6cd1.c7492b53.js | 1 + assets/js/4feb6cd1.caac4977.js | 1 - assets/js/509ab375.66a99c27.js | 1 + assets/js/509ab375.ead64830.js | 1 - assets/js/50f6977b.67d8e26f.js | 1 + assets/js/50f6977b.8f223948.js | 1 - assets/js/51b39968.9b1d98cf.js | 1 + assets/js/51b39968.f299113a.js | 1 - assets/js/51cf57e0.1b8f89dc.js | 1 + assets/js/51cf57e0.b782c227.js | 1 - assets/js/526a9c93.1b10d765.js | 1 - assets/js/526a9c93.5f7bf9f4.js | 1 + assets/js/52a67732.0a288ef1.js | 1 + assets/js/52a67732.9b5e41e7.js | 1 - assets/js/53346373.f59e03d1.js | 1 + assets/js/53ae6633.d227b258.js | 1 + assets/js/53ae6633.faa11e37.js | 1 - assets/js/53eeef0b.2bca39df.js | 1 - assets/js/53eeef0b.e0114c41.js | 1 + assets/js/546a9229.544d52d1.js | 1 - assets/js/546a9229.854acb31.js | 1 + assets/js/54e62810.05537c28.js | 1 + assets/js/54e62810.67d1806c.js | 1 - assets/js/55ca2829.e290df63.js | 1 + assets/js/55ca2829.f76385a4.js | 1 - assets/js/567b9119.5cdfc1e0.js | 1 + assets/js/567b9119.6b742e66.js | 1 - assets/js/56d3718f.427da004.js | 1 + assets/js/56d3718f.80f4b70b.js | 1 - assets/js/56f07039.765500fd.js | 1 + assets/js/56f07039.cf34dcdd.js | 1 - assets/js/56f286e3.7b765b7d.js | 1 + assets/js/56f286e3.83745087.js | 1 - assets/js/570846ac.3a3ff9f9.js | 1 - assets/js/570846ac.e37364d6.js | 1 + assets/js/5785daff.4831c765.js | 1 - assets/js/5785daff.a5456c80.js | 1 + assets/js/578a4822.1b11cf31.js | 1 + assets/js/578a4822.8daf9a72.js | 1 - assets/js/5801c226.642b38ea.js | 1 - assets/js/5801c226.75a49e22.js | 1 + assets/js/5882ca40.09c3a83e.js | 1 + assets/js/5882ca40.53992464.js | 1 - assets/js/58a4f9c4.c452149b.js | 1 - assets/js/58a4f9c4.d768bb7a.js | 1 + assets/js/58a95835.26c0966b.js | 1 + assets/js/58a95835.9a7e0577.js | 1 - assets/js/598cf0cc.4f021386.js | 1 + assets/js/598cf0cc.6808770b.js | 1 - assets/js/59a6ed9f.ca190933.js | 1 + assets/js/59a6ed9f.f9ae4ac7.js | 1 - assets/js/5a72d50a.b820c0b7.js | 1 + assets/js/5a72d50a.cc0e8df4.js | 1 - assets/js/5ab2e4c0.f49471e0.js | 1 + assets/js/5ad71dc2.68957121.js | 1 + assets/js/5ad71dc2.71f5f4ac.js | 1 - assets/js/5b1e20a2.31d06d8f.js | 1 - assets/js/5b1e20a2.d41b574b.js | 1 + assets/js/5c3859ae.89ed20b7.js | 1 + assets/js/5c3859ae.d6435eaa.js | 1 - assets/js/5ce5f8b6.2197cedc.js | 1 + assets/js/5ce5f8b6.453640c9.js | 1 - assets/js/5d5a7f04.0b64332d.js | 1 + assets/js/5d5a7f04.639e35c2.js | 1 - assets/js/5d5c5f94.beff32a9.js | 1 - assets/js/5d5c5f94.f8ff9e5a.js | 1 + assets/js/5dab2dcc.03daa588.js | 1 + assets/js/5dab2dcc.2d3906bb.js | 1 - assets/js/5dd64854.591acd39.js | 1 - assets/js/5dd64854.94b510e0.js | 1 + assets/js/5dd80f8d.252ea40f.js | 1 + assets/js/5dd80f8d.ef5b2267.js | 1 - assets/js/5e1c13c1.725a83a9.js | 1 + assets/js/5e1c13c1.af5ef71e.js | 1 - assets/js/5e662b40.504204f1.js | 1 + assets/js/5e662b40.57ce37d1.js | 1 - assets/js/5e71fbd6.788ad15a.js | 1 - assets/js/5e71fbd6.d425c011.js | 1 + assets/js/5f0658da.0562c735.js | 1 - assets/js/5f0658da.be58f40d.js | 1 + assets/js/5f52e4de.3f7c4d4e.js | 1 + assets/js/5f52e4de.64872f7e.js | 1 - assets/js/5fee430a.1732644e.js | 1 - assets/js/5fee430a.a971530e.js | 1 + assets/js/60092ac2.5f5e2153.js | 1 - assets/js/60092ac2.cb1b742c.js | 1 + assets/js/608122d4.513c83d3.js | 1 + assets/js/608122d4.ef612457.js | 1 - assets/js/60813e77.3d66d983.js | 1 + assets/js/60813e77.c0720148.js | 1 - assets/js/615894c7.352766e1.js | 1 - assets/js/615894c7.c65023bf.js | 1 + assets/js/62001d57.5aeb8af1.js | 1 + assets/js/62001d57.c96015b1.js | 1 - assets/js/6202e9b0.25734e4e.js | 1 + assets/js/6202e9b0.d63dafb9.js | 1 - assets/js/627191fc.20d9e81c.js | 1 - assets/js/627191fc.f9a6f7a4.js | 1 + assets/js/62770d20.5c835552.js | 1 + assets/js/62770d20.d8fe7b6d.js | 1 - assets/js/6396a7fe.490d79d8.js | 1 + assets/js/6396a7fe.61a31dcc.js | 1 - assets/js/63f503ba.358aa8cb.js | 1 + assets/js/63f503ba.885e1353.js | 1 - assets/js/64611c9e.006ed455.js | 1 - assets/js/64611c9e.fa02ea1c.js | 1 + assets/js/65092830.b8ecad87.js | 1 - .../{34cb51de.65478ef8.js => 65092830.f2c41dec.js} | 2 +- assets/js/652bfc64.2188c1b2.js | 1 - assets/js/652bfc64.229d7087.js | 1 + assets/js/656a92e7.e21e3307.js | 1 + assets/js/657d8ebd.0f987ef2.js | 1 - assets/js/657d8ebd.c5028931.js | 1 + assets/js/65901721.47e584bf.js | 1 - assets/js/65901721.e21bc337.js | 1 + assets/js/65c0386d.13a4d3b1.js | 1 + assets/js/65c0386d.dbe84a9d.js | 1 - assets/js/65c96e54.25d5b87f.js | 1 - assets/js/65c96e54.d35dd311.js | 1 + assets/js/66a8c7f6.12b39e4b.js | 1 - assets/js/66a8c7f6.85902c67.js | 1 + assets/js/66cba0bd.60d2da65.js | 1 - assets/js/66cba0bd.faa47e96.js | 1 + assets/js/66f3d752.33d82cfe.js | 1 + assets/js/66f70f8f.4dcf0982.js | 1 + assets/js/66f70f8f.85a454bc.js | 1 - assets/js/673116d2.669abe58.js | 1 - assets/js/673116d2.efd92223.js | 1 + assets/js/6742155e.ae4cdb1b.js | 1 + assets/js/6742155e.f14690e8.js | 1 - assets/js/67533fec.02f4ab6f.js | 1 - assets/js/67533fec.0a3747e2.js | 1 + assets/js/682b4d18.5f92bb5d.js | 1 + assets/js/682b4d18.ff9f6fcd.js | 1 - .../{4ee76bca.9d9c855d.js => 68387aed.6c485782.js} | 2 +- assets/js/68387aed.9c37a528.js | 1 - assets/js/687745aa.e3a44f5e.js | 1 + assets/js/687745aa.ee3b15f1.js | 1 - assets/js/689c4956.4032913c.js | 1 + assets/js/689c4956.f2bffe74.js | 1 - assets/js/68ebab0c.26c51eb9.js | 1 + assets/js/68ebab0c.505e71ff.js | 1 - assets/js/68fb1eeb.6f093b68.js | 1 + assets/js/68fb1eeb.737dc961.js | 1 - assets/js/6920b208.2ca39706.js | 1 - assets/js/6920b208.ccc76c5e.js | 1 + assets/js/6996b984.b4f73bc7.js | 1 + assets/js/6996b984.becc3d7a.js | 1 - assets/js/6a657091.6e7caf8d.js | 1 - assets/js/6a657091.913fe8e5.js | 1 + assets/js/6a7380a0.db9ff9dc.js | 1 + assets/js/6a7380a0.f99d149b.js | 1 - assets/js/6a9eab1e.228f065d.js | 1 - assets/js/6a9eab1e.ab3db223.js | 1 + assets/js/6b15d84e.71996085.js | 1 - assets/js/6b15d84e.febcf29d.js | 1 + assets/js/6bcde730.41fdc0f4.js | 1 + assets/js/6bcde730.eb670e8a.js | 1 - assets/js/6c2831f5.4e93601b.js | 1 + assets/js/6c2831f5.aeb89dd2.js | 1 - assets/js/6cbc9f75.289091a9.js | 1 - assets/js/6cbc9f75.67d4a2a1.js | 1 + assets/js/6d5f83d2.7366a0a9.js | 1 - assets/js/6d5f83d2.aa331710.js | 1 + assets/js/6d989d91.1a76ebf5.js | 1 - assets/js/6d989d91.b21d4122.js | 1 + assets/js/6db5822b.41ba9d22.js | 1 + assets/js/6db5822b.86299f29.js | 1 - assets/js/6e20e454.782e3b18.js | 1 - assets/js/6e20e454.dd6fb97b.js | 1 + assets/js/6e60fc8b.3ac840de.js | 1 - assets/js/6e60fc8b.aca356a4.js | 1 + assets/js/6e84f360.67048bd3.js | 1 + assets/js/6e84f360.bd55039b.js | 1 - assets/js/6f1c5025.392919f0.js | 1 + assets/js/6f1c5025.657daeda.js | 1 - assets/js/6f91cedb.1268824b.js | 1 - assets/js/6f91cedb.dae20d28.js | 1 + assets/js/700a6203.96e5b25a.js | 1 + assets/js/700a6203.e6792e5f.js | 1 - assets/js/702c04ed.4a8f4c3a.js | 1 + assets/js/702c04ed.f33c7e72.js | 1 - assets/js/706586ad.13f6fcf8.js | 1 - assets/js/706586ad.d57f0c83.js | 1 + assets/js/7173f453.0649e776.js | 1 - assets/js/7173f453.9127f4e0.js | 1 + assets/js/71f0a91e.b8762e40.js | 1 - assets/js/71f0a91e.c2b43331.js | 1 + assets/js/72623072.5efc9424.js | 1 - .../{727dcb34.3bb0a6db.js => 72623072.7338e10b.js} | 2 +- assets/js/726258db.05a4fdc5.js | 1 + assets/js/726258db.be87e2de.js | 1 - assets/js/727dcb34.5a1cbb5e.js | 1 + assets/js/728e4eed.0709a7d1.js | 1 + assets/js/728e4eed.d208fba0.js | 1 - assets/js/7331483d.028c6ffa.js | 1 - assets/js/7331483d.53a5e6d9.js | 1 + assets/js/7349646d.56979680.js | 1 + assets/js/7349646d.f03fb996.js | 1 - assets/js/73e069de.db6dff06.js | 1 - assets/js/73e069de.df6d46b3.js | 1 + assets/js/740a4079.a9309d7a.js | 1 - assets/js/740a4079.c9341847.js | 1 + assets/js/747296f3.b4b16fbf.js | 1 + assets/js/747296f3.f8fc9c88.js | 1 - assets/js/74cc64ea.7b804d3a.js | 1 + assets/js/74cc64ea.fb92a9b6.js | 1 - assets/js/74dddc49.9d85aa84.js | 1 + assets/js/7666c3a3.b0635687.js | 1 + assets/js/7666c3a3.ef3ecff1.js | 1 - assets/js/768b23eb.5a9f0e97.js | 1 + assets/js/768b23eb.e091e96e.js | 1 - assets/js/76c7e13e.cca1f363.js | 1 + assets/js/76c7e13e.e4799098.js | 1 - assets/js/774da543.b44038d8.js | 1 - assets/js/774da543.b4549ecc.js | 1 + assets/js/775f7402.56e7aa31.js | 1 - assets/js/775f7402.a8a3553d.js | 1 + assets/js/7766e9a3.bb4686eb.js | 1 - assets/js/7766e9a3.f7467a5f.js | 1 + assets/js/77bc4eed.16348cfe.js | 1 - assets/js/77bc4eed.ae89a841.js | 1 + assets/js/782adcf0.209702cb.js | 1 - assets/js/782adcf0.e9d6f902.js | 1 + assets/js/783ac7c2.24f9c08a.js | 1 + assets/js/783ac7c2.c10d29c5.js | 1 - assets/js/78ba9b90.4e1bd74b.js | 1 + assets/js/78ba9b90.fbe39829.js | 1 - assets/js/78bf798d.07e36339.js | 1 - assets/js/78bf798d.57aa4d10.js | 1 + assets/js/794916e1.387f08b1.js | 1 - assets/js/794916e1.491ace61.js | 1 + assets/js/795486c3.042a464f.js | 1 - assets/js/795486c3.571c29ca.js | 1 + assets/js/7968a6dd.aaeb7699.js | 1 + assets/js/7968a6dd.fb698d2d.js | 1 - assets/js/79c0e773.e680352b.js | 1 + assets/js/7a6da112.57a10992.js | 1 - assets/js/7a6da112.efceb975.js | 1 + assets/js/7a9ccdde.742fd52e.js | 1 + assets/js/7a9ccdde.9340217b.js | 1 - assets/js/7a9ef260.849eae86.js | 1 - .../{0ae680de.c99e2d2c.js => 7a9ef260.b1c7cad6.js} | 2 +- assets/js/7abea912.45ef7cb4.js | 1 + assets/js/7abea912.a3b9d891.js | 1 - assets/js/7acfad2d.0d009458.js | 1 + assets/js/7acfad2d.4e71b179.js | 1 - assets/js/7b4c5d89.981aa6c4.js | 1 + assets/js/7b4c5d89.d9d3ced3.js | 1 - assets/js/7b7ce1bb.b1f36699.js | 1 - assets/js/7b7ce1bb.fb591d47.js | 1 + assets/js/7c3088cd.88920ebf.js | 1 - assets/js/7c3088cd.b77025a2.js | 1 + assets/js/7c81245b.3f7ff4d2.js | 1 - assets/js/7c81245b.d396282e.js | 1 + assets/js/7ca28631.c626d6c2.js | 1 - assets/js/7ca28631.cf3fe47d.js | 1 + assets/js/7ce1d7ba.4c892343.js | 1 + assets/js/7ce1d7ba.eee60331.js | 1 - assets/js/7d540a1c.2c0773f4.js | 1 + assets/js/7d540a1c.f06351bb.js | 1 - assets/js/7de80a04.2ac7aa53.js | 1 - assets/js/7de80a04.baea3f7c.js | 1 + assets/js/7e1818ad.bde2e8d8.js | 1 - assets/js/7e1818ad.c358bcce.js | 1 + assets/js/7e9d6c07.713ea52f.js | 1 - assets/js/7e9d6c07.8f123222.js | 1 + assets/js/7ea4dca7.050efccb.js | 1 + assets/js/7ea4dca7.1bea8506.js | 1 - assets/js/7f4ab349.9d4b95b6.js | 1 - assets/js/7f4ab349.f5cbe695.js | 1 + assets/js/7f4c5c7b.221ae515.js | 1 - assets/js/7f4c5c7b.9b49b785.js | 1 + assets/js/7f9ffb40.143a22ba.js | 1 - assets/js/7f9ffb40.425fe902.js | 1 + assets/js/7fa6c7d7.621aef7a.js | 1 + assets/js/7fa6c7d7.abbaa74a.js | 1 - assets/js/7fdd84c3.7851bc0c.js | 1 + assets/js/7fdd84c3.b7b7143f.js | 1 - .../{fb61b539.ef5d6189.js => 7ff8ae66.91a83928.js} | 2 +- assets/js/7ff8ae66.adc82365.js | 1 - assets/js/8038297c.4b1d6c16.js | 1 - assets/js/8038297c.55055184.js | 1 + assets/js/807a296b.3d83cb0d.js | 1 + assets/js/807a296b.f0db713e.js | 1 - assets/js/81c00f7a.a8bd4bcc.js | 1 + assets/js/81c00f7a.d07c0a8e.js | 1 - .../{5ab2e4c0.782e7a72.js => 822c4cd0.1e8acb80.js} | 2 +- assets/js/822c4cd0.550004ca.js | 1 - .../{11415922.86d9309c.js => 8235289d.4871563d.js} | 2 +- assets/js/8235289d.b5061697.js | 1 - assets/js/82e28990.92e307dc.js | 1 + assets/js/82e28990.cfaf30af.js | 1 - assets/js/837a6211.05aa0106.js | 1 + assets/js/837a6211.2ffc4089.js | 1 - assets/js/83caed44.43ec86bc.js | 1 + assets/js/83caed44.6b08ae13.js | 1 - assets/js/83fbfe62.b0f06499.js | 1 + assets/js/83fbfe62.d227a287.js | 1 - assets/js/84328430.4ca5699f.js | 1 - assets/js/84328430.f5149255.js | 1 + assets/js/845d6e8e.1909746f.js | 1 - assets/js/845d6e8e.487273e9.js | 1 + assets/js/84eeefe6.37c5ccb6.js | 1 - assets/js/84eeefe6.dae70540.js | 1 + .../{fd0ee3c6.61056912.js => 84faaee0.2d344468.js} | 2 +- assets/js/84faaee0.6eb99f25.js | 1 - assets/js/8526f5f6.a458fa75.js | 1 - assets/js/8526f5f6.e9068c90.js | 1 + assets/js/85618d7a.50311b87.js | 1 + assets/js/85618d7a.5a8afe71.js | 1 - assets/js/85811646.0fb00ca3.js | 1 - assets/js/85811646.91532574.js | 1 + assets/js/86802c4c.8ea7b443.js | 1 + assets/js/86802c4c.e57750ec.js | 1 - assets/js/868dd308.14f7b41c.js | 1 + assets/js/868dd308.e92ff638.js | 1 - assets/js/87542a62.1b49b92a.js | 1 - assets/js/87542a62.cad825b0.js | 1 + assets/js/8853f2c2.220d2c15.js | 1 + assets/js/8853f2c2.5ee3e40d.js | 1 - .../{1d2426fc.723beb65.js => 885a7d6a.42a1b0d6.js} | 2 +- assets/js/885a7d6a.e4dcab5c.js | 1 - assets/js/8865241c.149ab5cd.js | 1 - assets/js/8865241c.eb758e6c.js | 1 + assets/js/8866cdc6.78170166.js | 1 - assets/js/8866cdc6.f2a0408b.js | 1 + assets/js/88b3827b.026a2161.js | 1 + assets/js/88b3827b.7f50d46d.js | 1 - assets/js/88fe791b.1bc618ab.js | 1 + assets/js/88fe791b.4b1aa31a.js | 1 - assets/js/895dee77.e3366a0f.js | 1 - assets/js/895dee77.fb50ae5c.js | 1 + assets/js/899fb7ad.0855184c.js | 1 + assets/js/899fb7ad.4f693ba9.js | 1 - assets/js/89ca3add.3b674072.js | 1 + assets/js/89ca3add.3eb9ec9a.js | 1 - assets/js/8b7b5312.b2d3196f.js | 1 + assets/js/8b7b5312.f5664dc9.js | 1 - assets/js/8c6e7842.b3f5d0a0.js | 1 + assets/js/8c6e7842.d70de832.js | 1 - assets/js/8d08212b.4cd5d329.js | 1 - .../{a7750664.8bc6753d.js => 8d08212b.f53c6cb2.js} | 2 +- assets/js/8d2c35d4.1fd44b34.js | 1 - assets/js/8d2c35d4.c633d23f.js | 1 + assets/js/8dc9f855.bbdaaf47.js | 1 + assets/js/8dc9f855.ea1fdf8f.js | 1 - assets/js/8e81a754.081f2590.js | 1 + assets/js/8e81a754.1f78dc3b.js | 1 - assets/js/8eb806f1.616ce5b5.js | 1 + assets/js/8eb806f1.74a75e1b.js | 1 - assets/js/8eeb7ef3.334acc23.js | 1 - assets/js/8eeb7ef3.a30db3ae.js | 1 + assets/js/8ef337ca.17610190.js | 1 - assets/js/8ef337ca.38d95d08.js | 1 + assets/js/8f60a0b3.33e3c536.js | 1 + assets/js/8f60a0b3.80d0d86d.js | 1 - assets/js/90a92006.11cbc061.js | 1 - assets/js/90a92006.f478e11f.js | 1 + assets/js/90dad6ee.2ba4bd93.js | 1 + assets/js/90dad6ee.77b931b5.js | 1 - assets/js/913f9301.afae53b5.js | 1 + assets/js/913f9301.dc12e4b5.js | 1 - assets/js/9142ac60.ace42db5.js | 1 - assets/js/9142ac60.d2a33e18.js | 1 + assets/js/91a30c6c.1b81304d.js | 1 - assets/js/91a30c6c.6223bea4.js | 1 + assets/js/91b81b98.36f13bee.js | 1 + assets/js/91b81b98.6e89d14e.js | 1 - assets/js/91cbd683.09f02c8a.js | 1 + assets/js/91cbd683.58dfcf19.js | 1 - assets/js/92574a95.a12cf8a7.js | 1 - assets/js/92574a95.bff193a9.js | 1 + assets/js/9262865a.392a33e6.js | 1 + assets/js/9262865a.bb6a2388.js | 1 - assets/js/931d717b.3a717e33.js | 1 - assets/js/931d717b.a83c1f7e.js | 1 + assets/js/932325e3.12326c77.js | 1 + assets/js/932325e3.8f3453ca.js | 1 - assets/js/93a69b01.bca7472f.js | 1 + assets/js/93a69b01.c7b22ad1.js | 1 - assets/js/93ce49f2.b92c22b6.js | 1 - assets/js/93ce49f2.ec513a16.js | 1 + assets/js/942689f6.3e875707.js | 1 + assets/js/942689f6.a83d794e.js | 1 - assets/js/943dca3e.33d026b4.js | 1 + assets/js/943dca3e.b89cfdee.js | 1 - assets/js/949da420.92c6afcd.js | 1 + assets/js/949da420.ca243db4.js | 1 - assets/js/94b95b8f.31bc4e87.js | 1 + assets/js/94b95b8f.6fe5a0b2.js | 1 - assets/js/94baf93c.1346c995.js | 1 + assets/js/94baf93c.e5255d89.js | 1 - assets/js/95033604.6c54c0f9.js | 1 - assets/js/95033604.6e0b92c9.js | 1 + assets/js/9522257f.63de51ed.js | 1 + assets/js/9522257f.6dabdd55.js | 1 - assets/js/955c0e5b.6bc4f2fc.js | 1 + assets/js/955c0e5b.96f77ef0.js | 1 - assets/js/95914a86.693fa2c3.js | 1 - assets/js/95914a86.e731d00e.js | 1 + assets/js/95a8058e.980b2f0d.js | 1 + assets/js/95a8058e.f549b041.js | 1 - assets/js/95c01cd8.51a21012.js | 1 + assets/js/95c01cd8.fe03e801.js | 1 - assets/js/961f481b.47c1dab2.js | 1 - assets/js/961f481b.8a8833a3.js | 1 + assets/js/965f64c7.c99d33ba.js | 1 - assets/js/965f64c7.f5dcb8be.js | 1 + assets/js/969375ac.2039b518.js | 1 + assets/js/969375ac.cc8f97ac.js | 1 - assets/js/98482f87.3a14148e.js | 1 - assets/js/98482f87.ba66c749.js | 1 + assets/js/986cf98d.9183506e.js | 1 - assets/js/986cf98d.eef99780.js | 1 + assets/js/98a5c5a6.722f5043.js | 1 + assets/js/98a5c5a6.8b4da06f.js | 1 - assets/js/991975ae.6f92fe43.js | 1 + assets/js/991975ae.ea6af4ba.js | 1 - assets/js/9961d4c6.4b28e906.js | 1 - assets/js/9961d4c6.c2163285.js | 1 + assets/js/99a448bd.d64e6414.js | 1 + assets/js/9afd861b.1e6d0ff8.js | 1 - assets/js/9afd861b.53375667.js | 1 + assets/js/9b395cf6.8b391952.js | 1 + assets/js/9b395cf6.e59243e4.js | 1 - assets/js/9b8cf09a.260b9fd5.js | 1 - assets/js/9b8cf09a.7ce01f1e.js | 1 + assets/js/9b8fa1b3.90180355.js | 1 + assets/js/9b8fa1b3.d10d4d75.js | 1 - assets/js/9ba4de84.a8e5689e.js | 1 - assets/js/9ba4de84.ef5d2119.js | 1 + assets/js/9bae3a4c.a4c72abc.js | 1 + assets/js/9bae3a4c.ddcdb0d5.js | 1 - assets/js/9c78aef9.1e9582a9.js | 1 - assets/js/9c78aef9.c393acac.js | 1 + assets/js/9c83163a.19279b88.js | 1 + assets/js/9c83163a.35fe8eb9.js | 1 - assets/js/9cc4f97f.47dc6e88.js | 1 + assets/js/9cc4f97f.83b18ef3.js | 1 - assets/js/9dd53394.65ea421d.js | 1 + assets/js/9dd53394.c731354a.js | 1 - assets/js/9e00d6e3.4d5d951e.js | 1 - assets/js/9e00d6e3.c2934eac.js | 1 + assets/js/9ecee934.3a26908e.js | 1 + assets/js/9ecee934.fe9e2e8b.js | 1 - assets/js/9f3200bd.1360fd7c.js | 1 - .../{3c7d7aed.326021a0.js => 9f3200bd.7c76d583.js} | 2 +- assets/js/9f710d35.61b64e3a.js | 1 + assets/js/9f710d35.8ac716b4.js | 1 - assets/js/9f8e45fd.00eb5db2.js | 1 + assets/js/9f8e45fd.ec4b51c9.js | 1 - assets/js/a04054f5.00728a15.js | 1 - assets/js/a04054f5.cba09eff.js | 1 + assets/js/a152e2a1.7b870a4d.js | 1 + assets/js/a152e2a1.f674210f.js | 1 - assets/js/a1972f12.4378dbcb.js | 1 + assets/js/a1972f12.79c7be37.js | 1 - assets/js/a1f54622.1e7dfb27.js | 1 + assets/js/a1f54622.dad77d20.js | 1 - assets/js/a2228310.144c4435.js | 1 + assets/js/a2228310.5227e7b0.js | 1 - assets/js/a222ac46.a29026af.js | 1 - assets/js/a222ac46.fe12bdf1.js | 1 + assets/js/a227e3bb.81c53baf.js | 1 - assets/js/a227e3bb.f7a5a0af.js | 1 + assets/js/a2379942.2970f651.js | 1 - assets/js/a2379942.568c7441.js | 1 + assets/js/a29568cd.263cc2c5.js | 1 + assets/js/a29568cd.fd893b77.js | 1 - assets/js/a2b3d820.42df04fe.js | 1 + assets/js/a2b3d820.a10cf547.js | 1 - assets/js/a2f052bb.6c125bef.js | 1 + assets/js/a2f052bb.a60b4a1d.js | 1 - assets/js/a3433b4a.1b9d5040.js | 1 - assets/js/a3433b4a.20c6ce95.js | 1 + assets/js/a3bdbb47.5c9d534a.js | 1 - assets/js/a3bdbb47.e100534f.js | 1 + assets/js/a4064c4a.a7117d3c.js | 1 - assets/js/a4064c4a.d44c39d0.js | 1 + assets/js/a43a10ce.8b121097.js | 1 - assets/js/a43a10ce.f8a1abc6.js | 1 + assets/js/a4731843.4aa10422.js | 1 + assets/js/a4731843.e8877402.js | 1 - assets/js/a56250de.32b055f3.js | 1 + assets/js/a56250de.5e0313e4.js | 1 - assets/js/a56a649d.972d90d6.js | 1 + assets/js/a56a649d.9fb527f8.js | 1 - assets/js/a5c83061.06197815.js | 1 + assets/js/a5c83061.34440fd9.js | 1 - assets/js/a5c8e3ee.0e93dcd6.js | 1 - assets/js/a5c8e3ee.ca2bd0a2.js | 1 + assets/js/a6347505.d2623b16.js | 1 - assets/js/a6347505.fa46a092.js | 1 + assets/js/a65aeb22.05854d06.js | 1 - assets/js/a65aeb22.882327db.js | 1 + assets/js/a6838072.4e97ee06.js | 1 - assets/js/a6838072.d5105d67.js | 1 + assets/js/a6a59c72.73c7cc8c.js | 1 + assets/js/a6a59c72.80aad573.js | 1 - assets/js/a6e67d36.1bcff134.js | 1 - assets/js/a6e67d36.293286ae.js | 1 + assets/js/a6f546c7.80e90cf4.js | 1 + assets/js/a6f546c7.94c52fef.js | 1 - assets/js/a7059e68.a3f1b60d.js | 1 + assets/js/a7059e68.eb1a7d00.js | 1 - assets/js/a7434e38.103a0bf2.js | 1 - assets/js/a7434e38.e7e01e27.js | 1 + assets/js/a7750664.61def123.js | 1 + assets/js/a85d3042.00032cd4.js | 1 + assets/js/a85d3042.e0bf13c4.js | 1 - assets/js/a8a78a40.a64b4581.js | 1 + assets/js/a8a78a40.d328644f.js | 1 - assets/js/a92c605c.1e410043.js | 1 + assets/js/a92c605c.2bcb927d.js | 1 - assets/js/a94703ab.74081b1d.js | 1 + assets/js/a94703ab.ed43bbde.js | 1 - assets/js/a99a7a84.43c2e13b.js | 1 - assets/js/a99a7a84.4a569cbd.js | 1 + assets/js/ab039f39.49d2752e.js | 1 - .../{66f3d752.7f8fdf7c.js => ab039f39.f8adde32.js} | 2 +- assets/js/abad1954.28a5cdfe.js | 1 - assets/js/abad1954.d1a61ab3.js | 1 + assets/js/abb8b5df.024ffd0b.js | 1 + assets/js/abb8b5df.122e1a24.js | 1 - assets/js/ac036e1a.5de1ac68.js | 1 - assets/js/ac036e1a.fac6ddbd.js | 1 + assets/js/ac18aa78.299f608f.js | 1 + assets/js/ac18aa78.bce15754.js | 1 - assets/js/ac305c95.27a1f7bb.js | 1 + assets/js/ac305c95.9523608a.js | 1 - assets/js/ac8215b1.6e7b6842.js | 1 - assets/js/ac8215b1.d1a41fbf.js | 1 + assets/js/aca294da.0357d2e2.js | 1 + assets/js/aca294da.218f25e0.js | 1 - assets/js/add034c7.86644d5e.js | 1 + assets/js/add034c7.afcb4611.js | 1 - assets/js/ae1a4dc5.3ccf2757.js | 1 + assets/js/ae1a4dc5.8debe308.js | 1 - assets/js/ae2933e0.7e46d046.js | 1 - assets/js/ae2933e0.bf9af1da.js | 1 + assets/js/ae61132c.054cbffa.js | 1 - assets/js/ae61132c.e80189e1.js | 1 + assets/js/ae7ab5ca.bb5fface.js | 1 + assets/js/ae7ab5ca.e1769ae9.js | 1 - assets/js/af09c9fa.4af5355c.js | 1 + assets/js/af09c9fa.ed66a051.js | 1 - assets/js/af189017.9fa1c39e.js | 1 - assets/js/af189017.ef0201fa.js | 1 + assets/js/afa9352b.07965f20.js | 1 + assets/js/afa9352b.6100ef08.js | 1 - assets/js/afc94b42.ac49af9d.js | 1 - assets/js/afc94b42.ef6dd603.js | 1 + assets/js/afe3f069.635e5561.js | 1 - assets/js/afe3f069.86a1a830.js | 1 + assets/js/afe76ad3.03926a60.js | 1 - assets/js/afe76ad3.2b19a28e.js | 1 + assets/js/b064ae39.6d4d3e73.js | 1 - assets/js/b064ae39.e90a9ae9.js | 1 + assets/js/b15cf43f.a350eca9.js | 1 - assets/js/b15cf43f.e2ee5769.js | 1 + assets/js/b1b1702b.1e5c93c4.js | 1 - assets/js/b1b1702b.d2345b03.js | 1 + assets/js/b1d4c921.6c5336f5.js | 1 + assets/js/b1d4c921.78452bfa.js | 1 - assets/js/b2214eb1.3ef66475.js | 1 + assets/js/b2214eb1.e13b9368.js | 1 - assets/js/b258137a.5657a8cc.js | 1 + assets/js/b258137a.d95a8760.js | 1 - assets/js/b27813ce.1bb9f03f.js | 1 - assets/js/b27813ce.5809c4ed.js | 1 + .../{79c0e773.a2544b1f.js => b2c09c04.1c8505b5.js} | 2 +- assets/js/b2c09c04.8a5b31d8.js | 1 - assets/js/b354a552.8ba8b65a.js | 1 + assets/js/b354a552.bb2070c0.js | 1 - assets/js/b3d255a8.4f717977.js | 1 + assets/js/b3d255a8.eafe1a61.js | 1 - assets/js/b487db90.d8dfc936.js | 1 - assets/js/b487db90.ec20f180.js | 1 + assets/js/b4b1dbe6.9d752ca4.js | 1 - assets/js/b4b1dbe6.a69557ad.js | 1 + assets/js/b4d23454.29d9e249.js | 1 + assets/js/b4d23454.79db2291.js | 1 - assets/js/b4f08813.1855444d.js | 1 - assets/js/b4f08813.984bb553.js | 1 + assets/js/b5493e20.0c765ef3.js | 1 - assets/js/b5493e20.ce949b2a.js | 1 + assets/js/b5b69494.96d93d10.js | 1 - assets/js/b5b69494.bebc807b.js | 1 + assets/js/b68a0da6.41a0aa15.js | 1 - assets/js/b68a0da6.7c19837a.js | 1 + assets/js/b695d366.4c8cc28c.js | 1 - assets/js/b695d366.7bc5d5fc.js | 1 + assets/js/b6bd0417.8092c106.js | 1 + assets/js/b6bd0417.f2d34759.js | 1 - assets/js/b85d43e2.5b8d814a.js | 1 - assets/js/b85d43e2.b6bdf0cf.js | 1 + assets/js/b8e59b2c.0a9f7c0e.js | 1 - assets/js/b8e59b2c.0b7afc2a.js | 1 + assets/js/b92b9889.c72ee478.js | 1 + assets/js/b92b9889.e3be9837.js | 1 - assets/js/b939d93e.656c71c1.js | 1 - assets/js/b939d93e.d0b11db7.js | 1 + assets/js/b9b95a14.1514e617.js | 1 - assets/js/b9b95a14.ab4399a9.js | 1 + assets/js/ba8f881f.4a933e9a.js | 1 + assets/js/ba8f881f.b798691c.js | 1 - assets/js/ba942c4a.926de97a.js | 1 + assets/js/ba942c4a.b9efcac7.js | 1 - assets/js/bb3b54eb.621ca474.js | 1 + assets/js/bb3b54eb.fb334890.js | 1 - assets/js/bb7ff5c7.0831e5cd.js | 1 - assets/js/bb7ff5c7.7b7d83e4.js | 1 + assets/js/bbe812b2.226d9347.js | 1 - assets/js/bbe812b2.f93181ac.js | 1 + assets/js/bc0e42ae.4a3c9cef.js | 1 - assets/js/bc0e42ae.f3014624.js | 1 + assets/js/bc158748.81faac3c.js | 1 - assets/js/bc158748.8edd1e0a.js | 1 + assets/js/bc580689.168fe4ba.js | 1 - assets/js/bc580689.aaa89f18.js | 1 + assets/js/bc72aaf9.07b6e644.js | 1 - assets/js/bc72aaf9.9c555370.js | 1 + assets/js/bcaec485.924c50cd.js | 1 - assets/js/bcaec485.c0f82cc2.js | 1 + assets/js/bced3f71.4aff0b2b.js | 1 - assets/js/bced3f71.c6848614.js | 1 + assets/js/bd9dcf8a.bcaf680c.js | 1 + assets/js/bd9dcf8a.c543192c.js | 1 - assets/js/be191a2f.2e971851.js | 1 + assets/js/be191a2f.d666565b.js | 1 - assets/js/be47e46c.23a795fc.js | 1 - assets/js/be47e46c.a09eeb56.js | 1 + assets/js/bfa69319.a5ece7bf.js | 1 - assets/js/bfa69319.c71d9255.js | 1 + assets/js/bfb8c06b.04aafba0.js | 1 - assets/js/bfb8c06b.34868e2b.js | 1 + assets/js/c05e6243.632a34b2.js | 1 + assets/js/c05e6243.b883b197.js | 1 - assets/js/c1a2c389.870fa00f.js | 1 + assets/js/c1a2c389.cc12095d.js | 1 - assets/js/c34fec7a.4c361055.js | 1 - assets/js/c34fec7a.8c409f6f.js | 1 + assets/js/c3b7d73e.60b98df8.js | 1 + assets/js/c3b7d73e.6a078ddd.js | 1 - assets/js/c3c1383c.9de4b2c7.js | 1 + assets/js/c3c1383c.fb4b970f.js | 1 - assets/js/c3c2cf0d.64ac343b.js | 1 - assets/js/c3c2cf0d.8af95259.js | 1 + assets/js/c3f10aa7.e949e8cb.js | 1 - assets/js/c3f10aa7.f665adb9.js | 1 + assets/js/c4dc49db.592414c9.js | 1 - assets/js/c4dc49db.f8f6b241.js | 1 + assets/js/c4f63a35.18366e52.js | 1 - assets/js/c4f63a35.ce34965f.js | 1 + assets/js/c51a5554.95cc16da.js | 1 - assets/js/c51a5554.ded96e4c.js | 1 + assets/js/c54faebb.0a09e519.js | 1 - .../{656a92e7.e8008734.js => c54faebb.d24bb846.js} | 2 +- assets/js/c55714c1.10a185e6.js | 1 - assets/js/c55714c1.4a3febaf.js | 1 + assets/js/c5e2ef47.10ddc021.js | 1 + assets/js/c5e2ef47.2767559f.js | 1 - assets/js/c6148b7b.7adc2b38.js | 1 - assets/js/c6148b7b.aedc22ee.js | 1 + assets/js/c679c49e.66e36f68.js | 1 - assets/js/c679c49e.83ffb8e6.js | 1 + assets/js/c68e47be.8230e904.js | 1 + assets/js/c68e47be.e81d9b32.js | 1 - assets/js/c6cb80e5.0f108168.js | 1 + assets/js/c6cb80e5.a3e29e81.js | 1 - assets/js/c75b9003.96f8a684.js | 1 - assets/js/c75b9003.e70c4ed2.js | 1 + assets/js/c7901ae7.975ad6b7.js | 1 - assets/js/c7901ae7.ef94f99b.js | 1 + assets/js/c80a87e5.20767268.js | 1 - assets/js/c80a87e5.2838282c.js | 1 + assets/js/c8415933.ac018e8c.js | 1 + assets/js/c8415933.c84ea069.js | 1 - assets/js/c85edbf4.2a0ba7e3.js | 1 - assets/js/c85edbf4.5014f68d.js | 1 + assets/js/c866602a.4378ae95.js | 1 - assets/js/c866602a.94cdfbfa.js | 1 + assets/js/c8b23694.b29c7f4c.js | 1 - assets/js/c8b23694.bb4dde32.js | 1 + assets/js/c8c040fd.ae4b02f1.js | 1 - assets/js/c8c040fd.fabc04ce.js | 1 + assets/js/c8d42f80.39faa782.js | 1 - assets/js/c8d42f80.d25e28c6.js | 1 + assets/js/c9264c9d.8225593c.js | 1 + assets/js/c9264c9d.8a29cd5c.js | 1 - assets/js/c926f228.041f2481.js | 1 + assets/js/c926f228.055a5786.js | 1 - assets/js/c9802e0f.76775190.js | 1 + assets/js/c9802e0f.cad55d94.js | 1 - assets/js/c9d8ba84.9889eb8a.js | 1 - assets/js/c9d8ba84.e7ce850c.js | 1 + assets/js/c9df2073.00f820bc.js | 1 - .../{3a6bbf33.0db4ae19.js => c9df2073.5d30817f.js} | 2 +- assets/js/ca516ab1.4c67cb96.js | 1 - assets/js/ca516ab1.a631cfb5.js | 1 + assets/js/ca823d8e.130e2e10.js | 1 + assets/js/ca823d8e.51afea5d.js | 1 - assets/js/ca88f7f6.7f644b3a.js | 1 + assets/js/ca88f7f6.acfc823d.js | 1 - assets/js/ca9696ff.94c2e157.js | 1 - assets/js/ca9696ff.accfe967.js | 1 + assets/js/ca9a1315.412149f7.js | 1 + assets/js/ca9a1315.dc0361ec.js | 1 - assets/js/cb1127ff.04b6a692.js | 1 - assets/js/cb1127ff.29f051a6.js | 1 + assets/js/cb6ed70c.1c8887b4.js | 1 + assets/js/cb6ed70c.c07e2af3.js | 1 - assets/js/cb7ce1df.837d758a.js | 1 + assets/js/cb7ce1df.f8cf63d3.js | 1 - assets/js/cb8aebd7.1cc26a81.js | 1 - assets/js/cb8aebd7.58c83db3.js | 1 + assets/js/cbefe8e6.20c007d1.js | 1 - assets/js/cbefe8e6.d024ab6e.js | 1 + assets/js/cc417f5b.b65cd895.js | 1 - assets/js/cc417f5b.e224d1b6.js | 1 + assets/js/cd1fd97e.37b9f5ef.js | 1 - assets/js/cd1fd97e.5bdccd93.js | 1 + assets/js/cdaeb6c7.6f357f99.js | 1 + assets/js/cdaeb6c7.df2df551.js | 1 - assets/js/ce1e026e.1867bc79.js | 1 + assets/js/ce1e026e.c5b4c67b.js | 1 - assets/js/ce3faf2d.23d2d6e9.js | 1 - assets/js/ce3faf2d.6f1571d9.js | 1 + assets/js/cee57922.17adfa9b.js | 1 + assets/js/cee57922.6d5b56df.js | 1 - assets/js/cf66eb9a.851599bd.js | 1 + assets/js/cf66eb9a.a8e51d9f.js | 1 - assets/js/cf73d354.6e96f0a4.js | 1 + assets/js/cf73d354.9b158036.js | 1 - assets/js/cf870e39.50637f5a.js | 1 - assets/js/cf870e39.7a0bbf02.js | 1 + assets/js/cfa831f6.9bd7c726.js | 1 - assets/js/cfa831f6.a3ef1de2.js | 1 + assets/js/cfa8b089.2654650c.js | 1 + assets/js/cfa8b089.eef179db.js | 1 - assets/js/cfb416dc.2ccf7923.js | 1 - assets/js/cfb416dc.2fb6a6d7.js | 1 + assets/js/cfda7dae.e4f6ed3f.js | 1 + assets/js/cfda7dae.fe188d50.js | 1 - assets/js/cfe35add.c291102a.js | 1 + assets/js/cfe35add.de35aac6.js | 1 - assets/js/d01c17fe.53bfc8f4.js | 1 - assets/js/d01c17fe.a861bb4f.js | 1 + assets/js/d02faa29.1e681f42.js | 1 + assets/js/d02faa29.e9248f9b.js | 1 - assets/js/d0711b6d.42c8f2df.js | 1 + assets/js/d0711b6d.85b75c47.js | 1 - assets/js/d07c7386.09443deb.js | 1 + assets/js/d07c7386.90fad743.js | 1 - assets/js/d0cd86ed.08a40290.js | 1 + assets/js/d0cd86ed.531bf319.js | 1 - assets/js/d0dab5bd.98023ad6.js | 1 + assets/js/d0dab5bd.f6748cbd.js | 1 - assets/js/d0e063b4.12510200.js | 1 + assets/js/d0e063b4.fdb2e57a.js | 1 - assets/js/d0e24277.58dd1984.js | 1 - assets/js/d0e24277.9ecd708b.js | 1 + assets/js/d1642eb0.08cc111f.js | 1 - assets/js/d1642eb0.248990b5.js | 1 + assets/js/d1da8056.76b7e6df.js | 1 - assets/js/d1da8056.bbfb4757.js | 1 + assets/js/d1f820e6.2567ee43.js | 1 - assets/js/d1f820e6.98d6fd2f.js | 1 + assets/js/d22c73ca.305928ed.js | 1 + assets/js/d22c73ca.dc6c6912.js | 1 - assets/js/d249d4cd.22221e35.js | 1 - assets/js/d249d4cd.dcbafdfe.js | 1 + assets/js/d32dcc20.3ef11828.js | 1 + assets/js/d32dcc20.3fbce5a2.js | 1 - assets/js/d3774da1.643e7434.js | 1 + assets/js/d3774da1.d07771e1.js | 1 - assets/js/d388c1c0.21ad8b7f.js | 1 + assets/js/d388c1c0.9d5a1ae0.js | 1 - assets/js/d39b0ace.4b669191.js | 1 - assets/js/d39b0ace.6f712eb7.js | 1 + assets/js/d41b86be.2441c8e9.js | 1 + assets/js/d41b86be.b2f8a13b.js | 1 - assets/js/d46d00ce.56054b22.js | 1 + assets/js/d46d00ce.6a7808e4.js | 1 - assets/js/d50422d0.8ea73767.js | 1 + assets/js/d50422d0.b9bfda39.js | 1 - assets/js/d505d09c.97f4652b.js | 1 - assets/js/d505d09c.fb00c194.js | 1 + assets/js/d565a856.28156f55.js | 1 - assets/js/d565a856.b60afede.js | 1 + assets/js/d5863f70.20f48776.js | 1 - assets/js/d5863f70.6a0f8935.js | 1 + assets/js/d58c4aef.0a940ec7.js | 1 - assets/js/d58c4aef.fb51545b.js | 1 + assets/js/d636f068.00b70d2f.js | 1 + assets/js/d636f068.3ccdb8b4.js | 1 - assets/js/d6467a7b.a5739b7c.js | 1 + assets/js/d6467a7b.e46b8a62.js | 1 - assets/js/d65f0d11.759d5ac0.js | 1 - assets/js/d65f0d11.eb4111cf.js | 1 + assets/js/d68a8932.1b5a522f.js | 1 + assets/js/d68a8932.e4d879a9.js | 1 - assets/js/d6b2ce60.0b775b00.js | 1 - assets/js/d6b2ce60.db005195.js | 1 + assets/js/d7fccb5c.1b2ba836.js | 1 + assets/js/d7fccb5c.dcac1a9d.js | 1 - assets/js/d8e67ba0.57982001.js | 1 - assets/js/d8e67ba0.bf7c219e.js | 1 + assets/js/d9120bf2.d4f61e45.js | 1 - assets/js/d9120bf2.fc753897.js | 1 + assets/js/d9135261.1a5f5d2d.js | 1 + assets/js/d9135261.78759909.js | 1 - .../{99a448bd.7ba4068b.js => d984a461.59ec4632.js} | 2 +- assets/js/d984a461.6f260e9f.js | 1 - assets/js/d9b89ec4.27e16f78.js | 1 - assets/js/d9b89ec4.3b19144b.js | 1 + assets/js/d9fbf9ee.5b173e0e.js | 1 + assets/js/d9fbf9ee.9b0b3890.js | 1 - assets/js/da50bba4.16de0ccc.js | 1 + assets/js/da50bba4.b307065b.js | 1 - assets/js/da6b5a00.ca5f497f.js | 1 + assets/js/da6b5a00.dc7521bb.js | 1 - assets/js/da8b62d5.1f0a74bc.js | 1 + assets/js/da8b62d5.e0e4cfeb.js | 1 - assets/js/dabc210e.b09a6698.js | 1 - assets/js/dabc210e.bafeb6df.js | 1 + assets/js/dad18bc2.5b4819f1.js | 1 + assets/js/dad18bc2.a8cd7721.js | 1 - assets/js/dbbd275b.0265e406.js | 1 - assets/js/dbbd275b.411a5113.js | 1 + assets/js/dc0b502e.9cc56b8b.js | 1 - assets/js/dc0b502e.c9fcee55.js | 1 + assets/js/dccfc6ca.cb51e9b5.js | 1 - assets/js/dccfc6ca.e572b874.js | 1 + assets/js/dd0d07c1.18865095.js | 1 + assets/js/dd0d07c1.689e9934.js | 1 - assets/js/dd697bad.7125556d.js | 1 + assets/js/dd697bad.81c6ffb9.js | 1 - assets/js/debad56b.2b7f41a2.js | 1 + assets/js/debad56b.4a0b6354.js | 1 - assets/js/debf7b3b.15092e15.js | 1 - assets/js/debf7b3b.c800f188.js | 1 + assets/js/decf5f3b.aa7b642a.js | 1 + assets/js/decf5f3b.b2ef684b.js | 1 - assets/js/ded3805b.d56523a7.js | 1 + assets/js/ded3805b.f23cb0ff.js | 1 - assets/js/df556f53.4f722245.js | 1 + assets/js/df556f53.9f8623a5.js | 1 - assets/js/dfd0c61c.f764b97a.js | 1 + assets/js/e0827474.2bcff7f1.js | 1 + assets/js/e0827474.cbc0a376.js | 1 - assets/js/e0af8c55.8ca17dc0.js | 1 + assets/js/e0af8c55.c8ae87c8.js | 1 - assets/js/e0d2da0e.2bf5fdc2.js | 1 + assets/js/e0d2da0e.729c3d0b.js | 1 - assets/js/e0e5f1df.d565dcaf.js | 1 - assets/js/e0e5f1df.e34392c9.js | 1 + assets/js/e113796f.baf9c36e.js | 1 - assets/js/e113796f.f18fe52d.js | 1 + assets/js/e13c5473.20a756a6.js | 1 + assets/js/e13c5473.9dc4d19d.js | 1 - assets/js/e13e97ed.cc93bbf2.js | 1 + assets/js/e13e97ed.d82eb3be.js | 1 - assets/js/e1492825.0e1d098e.js | 1 - assets/js/e1492825.1a398f6c.js | 1 + assets/js/e1957427.488c5b0f.js | 1 - assets/js/e1957427.62cc2f27.js | 1 + assets/js/e1b01fca.c4e24a49.js | 1 + assets/js/e1b01fca.d13b43a9.js | 1 - assets/js/e1c2e776.661131c0.js | 1 - assets/js/e1c2e776.cf5e4bee.js | 1 + assets/js/e1d07e5f.6056ce7c.js | 1 - assets/js/e1d07e5f.f169c77f.js | 1 + assets/js/e2266027.ca7058b6.js | 1 + assets/js/e2266027.cc89f3c4.js | 1 - assets/js/e23da508.5a3fcf75.js | 1 + assets/js/e3683d7e.77fb0b24.js | 1 - assets/js/e3683d7e.d7d535cc.js | 1 + assets/js/e49f040d.8979c140.js | 1 + assets/js/e49f040d.d9e088c1.js | 1 - assets/js/e519cd9e.309bf578.js | 1 + assets/js/e519cd9e.f17d13b9.js | 1 - assets/js/e54a7808.54e8c609.js | 1 + assets/js/e54a7808.bd165c91.js | 1 - assets/js/e57a39f4.a7d4aa52.js | 1 + assets/js/e57a39f4.cd4ad4f7.js | 1 - assets/js/e5dee6fa.1f05e79f.js | 1 + assets/js/e5dee6fa.e9235b5a.js | 1 - assets/js/e724aa0c.3d0a2fd2.js | 1 - assets/js/e724aa0c.fe902d00.js | 1 + assets/js/e795d793.a596b0d1.js | 1 + assets/js/e795d793.d3b3da14.js | 1 - .../{20c8a971.1235b424.js => e7c319aa.21b7fb82.js} | 2 +- assets/js/e7c319aa.66922067.js | 1 - assets/js/e8203627.a21ade88.js | 1 + assets/js/e8203627.add3bd8a.js | 1 - assets/js/e85b2b68.3cbf6efe.js | 1 - assets/js/e85b2b68.b2bc0b8c.js | 1 + assets/js/ea6b699b.28b42de3.js | 1 - assets/js/ea6b699b.c3fd2eee.js | 1 + assets/js/eaf7dfdf.1349bc60.js | 1 + assets/js/eaf7dfdf.3a1b03a5.js | 1 - assets/js/ec307c91.81ac9899.js | 1 - assets/js/ec307c91.dfc47eb0.js | 1 + assets/js/ec7c2dfb.4cab3e9d.js | 1 - assets/js/ec7c2dfb.e49d045a.js | 1 + assets/js/ec9cd171.dc66291f.js | 1 + assets/js/ec9cd171.f04964a0.js | 1 - assets/js/ec9e4b3c.302ca95b.js | 1 - assets/js/ec9e4b3c.7dbd47ed.js | 1 + assets/js/ecd40885.7c9b3f43.js | 1 + assets/js/ecd40885.82daba91.js | 1 - assets/js/ecfe08ed.20988fa1.js | 1 + assets/js/ecfe08ed.3807b562.js | 1 - assets/js/ee05e1f4.0cdb4c5f.js | 1 - assets/js/ee05e1f4.feb956d4.js | 1 + assets/js/eeb154ce.a4ba2e31.js | 1 - assets/js/eeb154ce.c464f72d.js | 1 + assets/js/ef17e2db.439b7677.js | 1 + assets/js/ef17e2db.4b09772d.js | 1 - assets/js/ef350d98.156b5372.js | 1 + assets/js/ef350d98.b875fb01.js | 1 - assets/js/ef5bbb0b.8e432cc4.js | 1 - assets/js/ef5bbb0b.be1d053d.js | 1 + .../{53346373.cc2df6da.js => f047be76.73e98be6.js} | 2 +- assets/js/f047be76.b24cb54d.js | 1 - assets/js/f0824f11.3d3a3486.js | 1 - assets/js/f0824f11.4eaff4be.js | 1 + assets/js/f0bcf997.013d8e2f.js | 1 - assets/js/f0bcf997.2c4c3aff.js | 1 + assets/js/f0f74909.116e6b8b.js | 1 - assets/js/f0f74909.7456614c.js | 1 + assets/js/f113d671.7d9d0b0b.js | 1 - assets/js/f113d671.c6a39c0f.js | 1 + assets/js/f12166ea.614e5dbd.js | 1 - assets/js/f12166ea.897ee306.js | 1 + assets/js/f1c8adb6.839ab4dd.js | 1 + assets/js/f1c8adb6.bd7bb9ed.js | 1 - assets/js/f211d1a3.30aa1881.js | 1 + assets/js/f211d1a3.f5dc7ca7.js | 1 - assets/js/f22722eb.1f48053d.js | 1 - assets/js/f22722eb.dd45234b.js | 1 + assets/js/f28290c6.d3d7d8fe.js | 1 + assets/js/f28290c6.f4917cc4.js | 1 - assets/js/f2a39581.694ea258.js | 1 + assets/js/f2a39581.f87e4643.js | 1 - assets/js/f2be4710.6d180ae7.js | 1 - assets/js/f2be4710.763f9ee7.js | 1 + assets/js/f2ce7b58.2ba3cbfe.js | 1 - assets/js/f2ce7b58.ccc2c689.js | 1 + assets/js/f331dae8.563330d5.js | 1 - assets/js/f331dae8.c054beb4.js | 1 + assets/js/f3ada91d.629c00a7.js | 1 - assets/js/f3ada91d.d2c1364d.js | 1 + assets/js/f44e39f1.9beb3af5.js | 1 + assets/js/f44e39f1.c99e836d.js | 1 - assets/js/f4ade6b7.1936d66f.js | 1 + assets/js/f4ade6b7.f165da54.js | 1 - assets/js/f57f08dc.47ac888a.js | 1 - assets/js/f57f08dc.b524e515.js | 1 + assets/js/f5b1c9e7.adb2fdd8.js | 1 + assets/js/f5b1c9e7.e19d0d75.js | 1 - assets/js/f6c54c06.7794838f.js | 1 - assets/js/f6c54c06.d6941501.js | 1 + assets/js/f6c94d23.993406df.js | 1 + assets/js/f6c94d23.e44ffdd8.js | 1 - assets/js/f6f4b6e7.5ac3be77.js | 1 + assets/js/f6f4b6e7.ed5e973a.js | 1 - assets/js/f756729a.e98b83ec.js | 1 - assets/js/f756729a.f9d98116.js | 1 + assets/js/f79beca4.4aed32b0.js | 1 - assets/js/f79beca4.e6deb386.js | 1 + assets/js/f7ff1d73.0419a74c.js | 1 + assets/js/f7ff1d73.ce4e9ccb.js | 1 - assets/js/f80e1b1f.0fcf9dff.js | 1 + assets/js/f80e1b1f.b85ab3ad.js | 1 - assets/js/f838c6f5.77827f68.js | 1 + assets/js/f838c6f5.c86f13b3.js | 1 - assets/js/f83908bc.15827dcc.js | 1 + assets/js/f83908bc.f207c64b.js | 1 - assets/js/f856d65b.03d1876d.js | 1 - assets/js/f856d65b.6991b249.js | 1 + assets/js/f8c10ed2.382cf68d.js | 1 - assets/js/f8c10ed2.7fedcf65.js | 1 + assets/js/f8d246d6.b7c0caab.js | 1 + assets/js/f8d246d6.fc7d6a61.js | 1 - assets/js/f8e2a94e.35a998b9.js | 1 - assets/js/f8e2a94e.e8bbee68.js | 1 + assets/js/f91fb9d4.17a61b02.js | 1 + assets/js/f91fb9d4.f334db20.js | 1 - assets/js/f9a81682.7234eec2.js | 1 - assets/js/f9a81682.f7f2d935.js | 1 + assets/js/fa425188.41feb8da.js | 1 + assets/js/fa425188.6cf49621.js | 1 - assets/js/fa6830dd.ac80adf6.js | 1 - .../{19099ebb.b2cd8e52.js => fa6830dd.b6f324cb.js} | 2 +- assets/js/fb61b539.20f561fa.js | 1 + assets/js/fba79747.d1182591.js | 1 - assets/js/fba79747.eac221dd.js | 1 + assets/js/fbb98df9.12e20a97.js | 1 - assets/js/fbb98df9.e3268bb8.js | 1 + assets/js/fbdd80d3.6befcd7f.js | 1 - assets/js/fbdd80d3.aa985285.js | 1 + assets/js/fbfd0f42.26abc53c.js | 1 + assets/js/fbfd0f42.f06087a3.js | 1 - assets/js/fd0ee3c6.b2a24103.js | 1 + .../{dfd0c61c.1c2ace93.js => fd890d09.42e11d81.js} | 2 +- assets/js/fd890d09.82a644ed.js | 1 - assets/js/fda8383b.756ab3f4.js | 1 + assets/js/fda8383b.94e04d32.js | 1 - assets/js/fddea1d0.3b495087.js | 1 + assets/js/fddea1d0.e17c3a78.js | 1 - assets/js/fdef3022.17db9d38.js | 1 + assets/js/fdef3022.378b56f9.js | 1 - assets/js/fdfe87c5.35a0378c.js | 1 + assets/js/fdfe87c5.6ba6bb75.js | 1 - assets/js/fe1988be.58275a38.js | 1 - assets/js/fe1988be.b190ba6a.js | 1 + assets/js/fe41fb76.2f6af41e.js | 1 + assets/js/fe41fb76.f708ab5c.js | 1 - assets/js/ff2e33f3.ce4ac25e.js | 1 + assets/js/ff2e33f3.ed657153.js | 1 - assets/js/main.5e3b2c86.js | 2 -- assets/js/main.6aef9bdc.js | 2 ++ ...6.js.LICENSE.txt => main.6aef9bdc.js.LICENSE.txt} | 0 ...ime~main.36102bb2.js => runtime~main.a80a79be.js} | 2 +- docs/1.12/contributing-guide/index.html | 12 ++++++------ docs/1.12/css-guidelines/index.html | 12 ++++++------ docs/1.12/discover/index.html | 12 ++++++------ docs/1.12/django-react-interop/index.html | 12 ++++++------ docs/1.12/docker-development/index.html | 12 ++++++------ docs/1.12/native-installation/index.html | 12 ++++++------ docs/1.13/building-the-frontend/index.html | 12 ++++++------ docs/1.13/contributing-guide/index.html | 12 ++++++------ docs/1.13/css-guidelines/index.html | 12 ++++++------ docs/1.13/discover/index.html | 12 ++++++------ docs/1.13/django-react-interop/index.html | 12 ++++++------ docs/1.13/docker-development/index.html | 12 ++++++------ docs/1.13/native-installation/index.html | 12 ++++++------ docs/1.14/building-the-frontend/index.html | 12 ++++++------ docs/1.14/contributing-guide/index.html | 12 ++++++------ docs/1.14/css-guidelines/index.html | 12 ++++++------ docs/1.14/discover/index.html | 12 ++++++------ docs/1.14/django-react-interop/index.html | 12 ++++++------ docs/1.14/docker-development/index.html | 12 ++++++------ docs/1.14/native-installation/index.html | 12 ++++++------ docs/1.15/building-the-frontend/index.html | 12 ++++++------ docs/1.15/contributing-guide/index.html | 10 +++++----- docs/1.15/css-guidelines/index.html | 12 ++++++------ docs/1.15/discover/index.html | 12 ++++++------ docs/1.15/django-react-interop/index.html | 10 +++++----- docs/1.15/docker-development/index.html | 12 ++++++------ docs/1.15/native-installation/index.html | 12 ++++++------ docs/1.16/accessibility-testing/index.html | 12 ++++++------ docs/1.16/building-the-frontend/index.html | 12 ++++++------ docs/1.16/contributing-guide/index.html | 12 ++++++------ docs/1.16/css-guidelines/index.html | 12 ++++++------ docs/1.16/discover/index.html | 12 ++++++------ docs/1.16/django-react-interop/index.html | 10 +++++----- docs/1.16/docker-development/index.html | 12 ++++++------ docs/1.16/native-installation/index.html | 12 ++++++------ docs/1.17/accessibility-testing/index.html | 12 ++++++------ docs/1.17/building-the-frontend/index.html | 12 ++++++------ docs/1.17/contributing-guide/index.html | 12 ++++++------ docs/1.17/css-guidelines/index.html | 12 ++++++------ docs/1.17/discover/index.html | 12 ++++++------ docs/1.17/django-react-interop/index.html | 10 +++++----- docs/1.17/docker-development/index.html | 12 ++++++------ docs/1.17/native-installation/index.html | 12 ++++++------ docs/2.0.0/accessibility-testing/index.html | 12 ++++++------ docs/2.0.0/building-the-frontend/index.html | 12 ++++++------ docs/2.0.0/contributing-guide/index.html | 12 ++++++------ docs/2.0.0/css-guidelines/index.html | 12 ++++++------ docs/2.0.0/discover/index.html | 12 ++++++------ docs/2.0.0/django-react-interop/index.html | 12 ++++++------ docs/2.0.0/docker-development/index.html | 12 ++++++------ docs/2.0.0/frontend-overrides/index.html | 12 ++++++------ docs/2.0.0/lms-connection/index.html | 12 ++++++------ docs/2.0.0/native-installation/index.html | 12 ++++++------ docs/2.0.1/accessibility-testing/index.html | 12 ++++++------ docs/2.0.1/building-the-frontend/index.html | 12 ++++++------ docs/2.0.1/contributing-guide/index.html | 12 ++++++------ docs/2.0.1/css-guidelines/index.html | 12 ++++++------ docs/2.0.1/discover/index.html | 12 ++++++------ docs/2.0.1/django-react-interop/index.html | 12 ++++++------ docs/2.0.1/docker-development/index.html | 12 ++++++------ docs/2.0.1/frontend-overrides/index.html | 12 ++++++------ docs/2.0.1/lms-connection/index.html | 12 ++++++------ docs/2.0.1/native-installation/index.html | 12 ++++++------ docs/2.1.0/accessibility-testing/index.html | 12 ++++++------ docs/2.1.0/building-the-frontend/index.html | 12 ++++++------ docs/2.1.0/contributing-guide/index.html | 12 ++++++------ docs/2.1.0/css-guidelines/index.html | 12 ++++++------ docs/2.1.0/discover/index.html | 12 ++++++------ docs/2.1.0/django-react-interop/index.html | 12 ++++++------ docs/2.1.0/docker-development/index.html | 12 ++++++------ docs/2.1.0/frontend-overrides/index.html | 12 ++++++------ docs/2.1.0/lms-connection/index.html | 12 ++++++------ docs/2.1.0/native-installation/index.html | 12 ++++++------ docs/2.10.0/accessibility-testing/index.html | 12 ++++++------ .../api/course-run-synchronization-api/index.html | 10 +++++----- docs/2.10.0/building-the-frontend/index.html | 12 ++++++------ docs/2.10.0/contributing-guide/index.html | 12 ++++++------ docs/2.10.0/css-guidelines/index.html | 12 ++++++------ docs/2.10.0/discover/index.html | 12 ++++++------ docs/2.10.0/displaying-connection-status/index.html | 10 +++++----- docs/2.10.0/django-react-interop/index.html | 12 ++++++------ docs/2.10.0/docker-development/index.html | 12 ++++++------ docs/2.10.0/frontend-overrides/index.html | 12 ++++++------ docs/2.10.0/internationalization/index.html | 12 ++++++------ docs/2.10.0/lms-backends/index.html | 10 +++++----- docs/2.10.0/lms-connection/index.html | 12 ++++++------ docs/2.10.0/native-installation/index.html | 12 ++++++------ docs/2.10.0/synchronizing-course-runs/index.html | 10 +++++----- docs/2.10.0/tls-connection/index.html | 10 +++++----- docs/2.10.0/web-analytics/index.html | 12 ++++++------ docs/2.11.0/accessibility-testing/index.html | 12 ++++++------ .../api/course-run-synchronization-api/index.html | 10 +++++----- docs/2.11.0/building-the-frontend/index.html | 12 ++++++------ docs/2.11.0/contributing-guide/index.html | 12 ++++++------ docs/2.11.0/css-guidelines/index.html | 12 ++++++------ docs/2.11.0/discover/index.html | 12 ++++++------ docs/2.11.0/displaying-connection-status/index.html | 10 +++++----- docs/2.11.0/django-react-interop/index.html | 12 ++++++------ docs/2.11.0/docker-development/index.html | 12 ++++++------ docs/2.11.0/frontend-overrides/index.html | 12 ++++++------ docs/2.11.0/internationalization/index.html | 12 ++++++------ docs/2.11.0/lms-backends/index.html | 10 +++++----- docs/2.11.0/lms-connection/index.html | 12 ++++++------ docs/2.11.0/native-installation/index.html | 12 ++++++------ docs/2.11.0/synchronizing-course-runs/index.html | 10 +++++----- docs/2.11.0/tls-connection/index.html | 10 +++++----- docs/2.11.0/web-analytics/index.html | 12 ++++++------ docs/2.12.0/accessibility-testing/index.html | 12 ++++++------ .../api/course-run-synchronization-api/index.html | 10 +++++----- docs/2.12.0/building-the-frontend/index.html | 12 ++++++------ docs/2.12.0/contributing-guide/index.html | 12 ++++++------ docs/2.12.0/css-guidelines/index.html | 12 ++++++------ docs/2.12.0/discover/index.html | 12 ++++++------ docs/2.12.0/displaying-connection-status/index.html | 10 +++++----- docs/2.12.0/django-react-interop/index.html | 12 ++++++------ docs/2.12.0/docker-development/index.html | 12 ++++++------ docs/2.12.0/frontend-overrides/index.html | 12 ++++++------ docs/2.12.0/internationalization/index.html | 12 ++++++------ docs/2.12.0/lms-backends/index.html | 10 +++++----- docs/2.12.0/lms-connection/index.html | 12 ++++++------ docs/2.12.0/native-installation/index.html | 12 ++++++------ docs/2.12.0/synchronizing-course-runs/index.html | 10 +++++----- docs/2.12.0/tls-connection/index.html | 10 +++++----- docs/2.12.0/web-analytics/index.html | 12 ++++++------ docs/2.13.0/accessibility-testing/index.html | 12 ++++++------ .../api/course-run-synchronization-api/index.html | 10 +++++----- docs/2.13.0/building-the-frontend/index.html | 12 ++++++------ docs/2.13.0/contributing-guide/index.html | 12 ++++++------ docs/2.13.0/css-guidelines/index.html | 12 ++++++------ docs/2.13.0/discover/index.html | 12 ++++++------ docs/2.13.0/displaying-connection-status/index.html | 10 +++++----- docs/2.13.0/django-react-interop/index.html | 12 ++++++------ docs/2.13.0/docker-development/index.html | 12 ++++++------ docs/2.13.0/frontend-overrides/index.html | 12 ++++++------ docs/2.13.0/internationalization/index.html | 12 ++++++------ docs/2.13.0/lms-backends/index.html | 10 +++++----- docs/2.13.0/lms-connection/index.html | 12 ++++++------ docs/2.13.0/native-installation/index.html | 12 ++++++------ docs/2.13.0/synchronizing-course-runs/index.html | 10 +++++----- docs/2.13.0/tls-connection/index.html | 10 +++++----- docs/2.13.0/web-analytics/index.html | 12 ++++++------ docs/2.14.0/accessibility-testing/index.html | 12 ++++++------ .../api/course-run-synchronization-api/index.html | 10 +++++----- docs/2.14.0/building-the-frontend/index.html | 12 ++++++------ docs/2.14.0/contributing-guide/index.html | 12 ++++++------ docs/2.14.0/css-guidelines/index.html | 12 ++++++------ docs/2.14.0/discover/index.html | 12 ++++++------ docs/2.14.0/displaying-connection-status/index.html | 10 +++++----- docs/2.14.0/django-react-interop/index.html | 12 ++++++------ docs/2.14.0/docker-development/index.html | 12 ++++++------ docs/2.14.0/frontend-overrides/index.html | 12 ++++++------ docs/2.14.0/internationalization/index.html | 12 ++++++------ docs/2.14.0/lms-backends/index.html | 10 +++++----- docs/2.14.0/lms-connection/index.html | 12 ++++++------ docs/2.14.0/native-installation/index.html | 12 ++++++------ docs/2.14.0/synchronizing-course-runs/index.html | 10 +++++----- docs/2.14.0/tls-connection/index.html | 10 +++++----- docs/2.14.0/web-analytics/index.html | 12 ++++++------ docs/2.14.1/accessibility-testing/index.html | 12 ++++++------ .../api/course-run-synchronization-api/index.html | 10 +++++----- docs/2.14.1/building-the-frontend/index.html | 12 ++++++------ docs/2.14.1/contributing-guide/index.html | 12 ++++++------ docs/2.14.1/cookiecutter/index.html | 12 ++++++------ docs/2.14.1/css-guidelines/index.html | 12 ++++++------ docs/2.14.1/discover/index.html | 10 +++++----- docs/2.14.1/displaying-connection-status/index.html | 10 +++++----- docs/2.14.1/django-react-interop/index.html | 12 ++++++------ docs/2.14.1/docker-development/index.html | 12 ++++++------ docs/2.14.1/frontend-overrides/index.html | 12 ++++++------ docs/2.14.1/installation/index.html | 12 ++++++------ docs/2.14.1/internationalization/index.html | 12 ++++++------ docs/2.14.1/joanie-connection/index.html | 10 +++++----- docs/2.14.1/lms-backends/index.html | 10 +++++----- docs/2.14.1/lms-connection/index.html | 12 ++++++------ docs/2.14.1/native-installation/index.html | 12 ++++++------ docs/2.14.1/synchronizing-course-runs/index.html | 10 +++++----- docs/2.14.1/tls-connection/index.html | 10 +++++----- docs/2.14.1/web-analytics/index.html | 12 ++++++------ docs/2.15.0/accessibility-testing/index.html | 12 ++++++------ .../api/course-run-synchronization-api/index.html | 10 +++++----- docs/2.15.0/building-the-frontend/index.html | 12 ++++++------ docs/2.15.0/contributing-guide/index.html | 12 ++++++------ docs/2.15.0/cookiecutter/index.html | 12 ++++++------ docs/2.15.0/css-guidelines/index.html | 12 ++++++------ docs/2.15.0/discover/index.html | 12 ++++++------ docs/2.15.0/displaying-connection-status/index.html | 10 +++++----- docs/2.15.0/django-react-interop/index.html | 12 ++++++------ docs/2.15.0/docker-development/index.html | 12 ++++++------ docs/2.15.0/frontend-overrides/index.html | 12 ++++++------ docs/2.15.0/installation/index.html | 12 ++++++------ docs/2.15.0/internationalization/index.html | 12 ++++++------ docs/2.15.0/joanie-connection/index.html | 10 +++++----- docs/2.15.0/lms-backends/index.html | 10 +++++----- docs/2.15.0/lms-connection/index.html | 12 ++++++------ docs/2.15.0/native-installation/index.html | 12 ++++++------ docs/2.15.0/synchronizing-course-runs/index.html | 10 +++++----- docs/2.15.0/tls-connection/index.html | 10 +++++----- docs/2.15.0/web-analytics/index.html | 12 ++++++------ docs/2.15.1/accessibility-testing/index.html | 12 ++++++------ .../api/course-run-synchronization-api/index.html | 10 +++++----- docs/2.15.1/building-the-frontend/index.html | 12 ++++++------ docs/2.15.1/contributing-guide/index.html | 12 ++++++------ docs/2.15.1/cookiecutter/index.html | 12 ++++++------ docs/2.15.1/css-guidelines/index.html | 12 ++++++------ docs/2.15.1/discover/index.html | 12 ++++++------ docs/2.15.1/displaying-connection-status/index.html | 10 +++++----- docs/2.15.1/django-react-interop/index.html | 12 ++++++------ docs/2.15.1/docker-development/index.html | 12 ++++++------ docs/2.15.1/frontend-overrides/index.html | 12 ++++++------ docs/2.15.1/installation/index.html | 12 ++++++------ docs/2.15.1/internationalization/index.html | 12 ++++++------ docs/2.15.1/joanie-connection/index.html | 10 +++++----- docs/2.15.1/lms-backends/index.html | 10 +++++----- docs/2.15.1/lms-connection/index.html | 12 ++++++------ docs/2.15.1/native-installation/index.html | 12 ++++++------ docs/2.15.1/synchronizing-course-runs/index.html | 10 +++++----- docs/2.15.1/tls-connection/index.html | 10 +++++----- docs/2.15.1/web-analytics/index.html | 12 ++++++------ docs/2.16.0/accessibility-testing/index.html | 12 ++++++------ .../api/course-run-synchronization-api/index.html | 10 +++++----- docs/2.16.0/building-the-frontend/index.html | 12 ++++++------ docs/2.16.0/contributing-guide/index.html | 12 ++++++------ docs/2.16.0/cookiecutter/index.html | 12 ++++++------ docs/2.16.0/css-guidelines/index.html | 12 ++++++------ docs/2.16.0/discover/index.html | 12 ++++++------ docs/2.16.0/displaying-connection-status/index.html | 10 +++++----- docs/2.16.0/django-react-interop/index.html | 12 ++++++------ docs/2.16.0/docker-development/index.html | 12 ++++++------ docs/2.16.0/frontend-overrides/index.html | 12 ++++++------ docs/2.16.0/installation/index.html | 12 ++++++------ docs/2.16.0/internationalization/index.html | 12 ++++++------ docs/2.16.0/joanie-connection/index.html | 10 +++++----- docs/2.16.0/lms-backends/index.html | 10 +++++----- docs/2.16.0/lms-connection/index.html | 12 ++++++------ docs/2.16.0/native-installation/index.html | 12 ++++++------ docs/2.16.0/synchronizing-course-runs/index.html | 10 +++++----- docs/2.16.0/tls-connection/index.html | 10 +++++----- docs/2.16.0/web-analytics/index.html | 12 ++++++------ docs/2.17.0/accessibility-testing/index.html | 12 ++++++------ .../api/course-run-synchronization-api/index.html | 10 +++++----- docs/2.17.0/building-the-frontend/index.html | 12 ++++++------ docs/2.17.0/contributing-guide/index.html | 12 ++++++------ docs/2.17.0/cookiecutter/index.html | 12 ++++++------ docs/2.17.0/css-guidelines/index.html | 12 ++++++------ docs/2.17.0/discover/index.html | 12 ++++++------ docs/2.17.0/displaying-connection-status/index.html | 10 +++++----- docs/2.17.0/django-react-interop/index.html | 12 ++++++------ docs/2.17.0/docker-development/index.html | 12 ++++++------ docs/2.17.0/filters-customization/index.html | 12 ++++++------ docs/2.17.0/frontend-overrides/index.html | 12 ++++++------ docs/2.17.0/installation/index.html | 12 ++++++------ docs/2.17.0/internationalization/index.html | 12 ++++++------ docs/2.17.0/joanie-connection/index.html | 10 +++++----- docs/2.17.0/lms-backends/index.html | 10 +++++----- docs/2.17.0/lms-connection/index.html | 12 ++++++------ docs/2.17.0/native-installation/index.html | 12 ++++++------ docs/2.17.0/synchronizing-course-runs/index.html | 10 +++++----- docs/2.17.0/tls-connection/index.html | 10 +++++----- docs/2.17.0/web-analytics/index.html | 12 ++++++------ docs/2.18.0/accessibility-testing/index.html | 12 ++++++------ .../api/course-run-synchronization-api/index.html | 10 +++++----- docs/2.18.0/building-the-frontend/index.html | 12 ++++++------ docs/2.18.0/contributing-guide/index.html | 12 ++++++------ docs/2.18.0/cookiecutter/index.html | 12 ++++++------ docs/2.18.0/css-guidelines/index.html | 12 ++++++------ docs/2.18.0/discover/index.html | 12 ++++++------ docs/2.18.0/displaying-connection-status/index.html | 10 +++++----- docs/2.18.0/django-react-interop/index.html | 12 ++++++------ docs/2.18.0/docker-development/index.html | 12 ++++++------ docs/2.18.0/filters-customization/index.html | 12 ++++++------ docs/2.18.0/frontend-overrides/index.html | 12 ++++++------ docs/2.18.0/installation/index.html | 12 ++++++------ docs/2.18.0/internationalization/index.html | 12 ++++++------ docs/2.18.0/joanie-connection/index.html | 10 +++++----- docs/2.18.0/lms-backends/index.html | 10 +++++----- docs/2.18.0/lms-connection/index.html | 12 ++++++------ docs/2.18.0/native-installation/index.html | 12 ++++++------ docs/2.18.0/synchronizing-course-runs/index.html | 10 +++++----- docs/2.18.0/tls-connection/index.html | 10 +++++----- docs/2.18.0/web-analytics/index.html | 12 ++++++------ docs/2.19.0/accessibility-testing/index.html | 12 ++++++------ .../api/course-run-synchronization-api/index.html | 10 +++++----- docs/2.19.0/building-the-frontend/index.html | 12 ++++++------ docs/2.19.0/contributing-guide/index.html | 12 ++++++------ docs/2.19.0/cookiecutter/index.html | 12 ++++++------ docs/2.19.0/css-guidelines/index.html | 12 ++++++------ docs/2.19.0/discover/index.html | 12 ++++++------ docs/2.19.0/displaying-connection-status/index.html | 10 +++++----- docs/2.19.0/django-react-interop/index.html | 12 ++++++------ docs/2.19.0/docker-development/index.html | 12 ++++++------ docs/2.19.0/filters-customization/index.html | 12 ++++++------ docs/2.19.0/frontend-overrides/index.html | 12 ++++++------ docs/2.19.0/installation/index.html | 12 ++++++------ docs/2.19.0/internationalization/index.html | 12 ++++++------ docs/2.19.0/joanie-connection/index.html | 10 +++++----- docs/2.19.0/lms-backends/index.html | 10 +++++----- docs/2.19.0/lms-connection/index.html | 12 ++++++------ docs/2.19.0/native-installation/index.html | 12 ++++++------ docs/2.19.0/synchronizing-course-runs/index.html | 10 +++++----- docs/2.19.0/tls-connection/index.html | 10 +++++----- docs/2.19.0/web-analytics/index.html | 12 ++++++------ docs/2.2.0/accessibility-testing/index.html | 12 ++++++------ docs/2.2.0/building-the-frontend/index.html | 12 ++++++------ docs/2.2.0/contributing-guide/index.html | 12 ++++++------ docs/2.2.0/css-guidelines/index.html | 12 ++++++------ docs/2.2.0/discover/index.html | 12 ++++++------ docs/2.2.0/django-react-interop/index.html | 12 ++++++------ docs/2.2.0/docker-development/index.html | 12 ++++++------ docs/2.2.0/frontend-overrides/index.html | 12 ++++++------ docs/2.2.0/internationalization/index.html | 12 ++++++------ docs/2.2.0/lms-connection/index.html | 12 ++++++------ docs/2.2.0/native-installation/index.html | 12 ++++++------ docs/2.20.0/accessibility-testing/index.html | 12 ++++++------ .../api/course-run-synchronization-api/index.html | 10 +++++----- docs/2.20.0/building-the-frontend/index.html | 12 ++++++------ docs/2.20.0/contributing-guide/index.html | 12 ++++++------ docs/2.20.0/cookiecutter/index.html | 12 ++++++------ docs/2.20.0/css-guidelines/index.html | 12 ++++++------ docs/2.20.0/discover/index.html | 12 ++++++------ docs/2.20.0/displaying-connection-status/index.html | 10 +++++----- docs/2.20.0/django-react-interop/index.html | 12 ++++++------ docs/2.20.0/docker-development/index.html | 12 ++++++------ docs/2.20.0/filters-customization/index.html | 12 ++++++------ docs/2.20.0/frontend-overrides/index.html | 12 ++++++------ docs/2.20.0/installation/index.html | 12 ++++++------ docs/2.20.0/internationalization/index.html | 12 ++++++------ docs/2.20.0/joanie-connection/index.html | 10 +++++----- docs/2.20.0/lms-backends/index.html | 10 +++++----- docs/2.20.0/lms-connection/index.html | 12 ++++++------ docs/2.20.0/native-installation/index.html | 12 ++++++------ docs/2.20.0/synchronizing-course-runs/index.html | 10 +++++----- docs/2.20.0/tls-connection/index.html | 10 +++++----- docs/2.20.0/web-analytics/index.html | 12 ++++++------ docs/2.20.1/accessibility-testing/index.html | 12 ++++++------ .../api/course-run-synchronization-api/index.html | 10 +++++----- docs/2.20.1/building-the-frontend/index.html | 12 ++++++------ docs/2.20.1/contributing-guide/index.html | 12 ++++++------ docs/2.20.1/cookiecutter/index.html | 12 ++++++------ docs/2.20.1/css-guidelines/index.html | 12 ++++++------ docs/2.20.1/discover/index.html | 12 ++++++------ docs/2.20.1/displaying-connection-status/index.html | 10 +++++----- docs/2.20.1/django-react-interop/index.html | 12 ++++++------ docs/2.20.1/docker-development/index.html | 12 ++++++------ docs/2.20.1/filters-customization/index.html | 12 ++++++------ docs/2.20.1/frontend-overrides/index.html | 12 ++++++------ docs/2.20.1/installation/index.html | 12 ++++++------ docs/2.20.1/internationalization/index.html | 12 ++++++------ docs/2.20.1/joanie-connection/index.html | 10 +++++----- docs/2.20.1/lms-backends/index.html | 10 +++++----- docs/2.20.1/lms-connection/index.html | 12 ++++++------ docs/2.20.1/native-installation/index.html | 12 ++++++------ docs/2.20.1/synchronizing-course-runs/index.html | 10 +++++----- docs/2.20.1/tls-connection/index.html | 10 +++++----- docs/2.20.1/web-analytics/index.html | 12 ++++++------ docs/2.21.0/accessibility-testing/index.html | 12 ++++++------ .../api/course-run-synchronization-api/index.html | 10 +++++----- docs/2.21.0/building-the-frontend/index.html | 12 ++++++------ docs/2.21.0/contributing-guide/index.html | 12 ++++++------ docs/2.21.0/cookiecutter/index.html | 12 ++++++------ docs/2.21.0/css-guidelines/index.html | 12 ++++++------ docs/2.21.0/discover/index.html | 12 ++++++------ docs/2.21.0/displaying-connection-status/index.html | 10 +++++----- docs/2.21.0/django-react-interop/index.html | 12 ++++++------ docs/2.21.0/docker-development/index.html | 12 ++++++------ docs/2.21.0/filters-customization/index.html | 12 ++++++------ docs/2.21.0/frontend-overrides/index.html | 12 ++++++------ docs/2.21.0/installation/index.html | 12 ++++++------ docs/2.21.0/internationalization/index.html | 12 ++++++------ docs/2.21.0/joanie-connection/index.html | 10 +++++----- docs/2.21.0/lms-backends/index.html | 10 +++++----- docs/2.21.0/lms-connection/index.html | 12 ++++++------ docs/2.21.0/native-installation/index.html | 12 ++++++------ docs/2.21.0/synchronizing-course-runs/index.html | 10 +++++----- docs/2.21.0/tls-connection/index.html | 10 +++++----- docs/2.21.0/web-analytics/index.html | 12 ++++++------ docs/2.21.1/accessibility-testing/index.html | 12 ++++++------ .../api/course-run-synchronization-api/index.html | 10 +++++----- docs/2.21.1/building-the-frontend/index.html | 12 ++++++------ docs/2.21.1/contributing-guide/index.html | 12 ++++++------ docs/2.21.1/cookiecutter/index.html | 12 ++++++------ docs/2.21.1/css-guidelines/index.html | 12 ++++++------ docs/2.21.1/discover/index.html | 12 ++++++------ docs/2.21.1/displaying-connection-status/index.html | 10 +++++----- docs/2.21.1/django-react-interop/index.html | 12 ++++++------ docs/2.21.1/docker-development/index.html | 12 ++++++------ docs/2.21.1/filters-customization/index.html | 12 ++++++------ docs/2.21.1/frontend-overrides/index.html | 12 ++++++------ docs/2.21.1/installation/index.html | 12 ++++++------ docs/2.21.1/internationalization/index.html | 12 ++++++------ docs/2.21.1/joanie-connection/index.html | 10 +++++----- docs/2.21.1/lms-backends/index.html | 10 +++++----- docs/2.21.1/lms-connection/index.html | 12 ++++++------ docs/2.21.1/native-installation/index.html | 12 ++++++------ docs/2.21.1/synchronizing-course-runs/index.html | 10 +++++----- docs/2.21.1/tls-connection/index.html | 10 +++++----- docs/2.21.1/web-analytics/index.html | 12 ++++++------ docs/2.22.0/accessibility-testing/index.html | 12 ++++++------ .../api/course-run-synchronization-api/index.html | 10 +++++----- docs/2.22.0/building-the-frontend/index.html | 12 ++++++------ docs/2.22.0/contributing-guide/index.html | 12 ++++++------ docs/2.22.0/cookiecutter/index.html | 12 ++++++------ docs/2.22.0/css-guidelines/index.html | 12 ++++++------ docs/2.22.0/discover/index.html | 12 ++++++------ docs/2.22.0/displaying-connection-status/index.html | 10 +++++----- docs/2.22.0/django-react-interop/index.html | 12 ++++++------ docs/2.22.0/docker-development/index.html | 12 ++++++------ docs/2.22.0/filters-customization/index.html | 12 ++++++------ docs/2.22.0/frontend-overrides/index.html | 12 ++++++------ docs/2.22.0/installation/index.html | 12 ++++++------ docs/2.22.0/internationalization/index.html | 12 ++++++------ docs/2.22.0/joanie-connection/index.html | 10 +++++----- docs/2.22.0/lms-backends/index.html | 10 +++++----- docs/2.22.0/lms-connection/index.html | 12 ++++++------ docs/2.22.0/native-installation/index.html | 12 ++++++------ docs/2.22.0/synchronizing-course-runs/index.html | 10 +++++----- docs/2.22.0/tls-connection/index.html | 10 +++++----- docs/2.22.0/web-analytics/index.html | 12 ++++++------ docs/2.23.0/accessibility-testing/index.html | 12 ++++++------ .../api/course-run-synchronization-api/index.html | 10 +++++----- docs/2.23.0/building-the-frontend/index.html | 12 ++++++------ docs/2.23.0/contributing-guide/index.html | 12 ++++++------ docs/2.23.0/cookiecutter/index.html | 12 ++++++------ docs/2.23.0/css-guidelines/index.html | 12 ++++++------ docs/2.23.0/discover/index.html | 12 ++++++------ docs/2.23.0/displaying-connection-status/index.html | 10 +++++----- docs/2.23.0/django-react-interop/index.html | 12 ++++++------ docs/2.23.0/docker-development/index.html | 12 ++++++------ docs/2.23.0/filters-customization/index.html | 12 ++++++------ docs/2.23.0/frontend-overrides/index.html | 12 ++++++------ docs/2.23.0/installation/index.html | 12 ++++++------ docs/2.23.0/internationalization/index.html | 12 ++++++------ docs/2.23.0/joanie-connection/index.html | 10 +++++----- docs/2.23.0/lms-backends/index.html | 10 +++++----- docs/2.23.0/lms-connection/index.html | 12 ++++++------ docs/2.23.0/native-installation/index.html | 12 ++++++------ docs/2.23.0/synchronizing-course-runs/index.html | 10 +++++----- docs/2.23.0/tls-connection/index.html | 10 +++++----- docs/2.23.0/web-analytics/index.html | 12 ++++++------ docs/2.24.0/accessibility-testing/index.html | 12 ++++++------ .../api/course-run-synchronization-api/index.html | 10 +++++----- docs/2.24.0/building-the-frontend/index.html | 12 ++++++------ docs/2.24.0/contributing-guide/index.html | 12 ++++++------ docs/2.24.0/cookiecutter/index.html | 12 ++++++------ docs/2.24.0/css-guidelines/index.html | 12 ++++++------ docs/2.24.0/discover/index.html | 12 ++++++------ docs/2.24.0/displaying-connection-status/index.html | 10 +++++----- docs/2.24.0/django-react-interop/index.html | 12 ++++++------ docs/2.24.0/docker-development/index.html | 12 ++++++------ docs/2.24.0/filters-customization/index.html | 12 ++++++------ docs/2.24.0/frontend-overrides/index.html | 12 ++++++------ docs/2.24.0/installation/index.html | 12 ++++++------ docs/2.24.0/internationalization/index.html | 12 ++++++------ docs/2.24.0/joanie-connection/index.html | 10 +++++----- docs/2.24.0/lms-backends/index.html | 10 +++++----- docs/2.24.0/lms-connection/index.html | 12 ++++++------ docs/2.24.0/native-installation/index.html | 12 ++++++------ docs/2.24.0/synchronizing-course-runs/index.html | 10 +++++----- docs/2.24.0/tls-connection/index.html | 10 +++++----- docs/2.24.0/web-analytics/index.html | 12 ++++++------ docs/2.24.1/accessibility-testing/index.html | 12 ++++++------ .../api/course-run-synchronization-api/index.html | 10 +++++----- docs/2.24.1/building-the-frontend/index.html | 12 ++++++------ docs/2.24.1/contributing-guide/index.html | 12 ++++++------ docs/2.24.1/cookiecutter/index.html | 12 ++++++------ docs/2.24.1/css-guidelines/index.html | 12 ++++++------ docs/2.24.1/discover/index.html | 12 ++++++------ docs/2.24.1/displaying-connection-status/index.html | 10 +++++----- docs/2.24.1/django-react-interop/index.html | 12 ++++++------ docs/2.24.1/docker-development/index.html | 12 ++++++------ docs/2.24.1/filters-customization/index.html | 12 ++++++------ docs/2.24.1/frontend-overrides/index.html | 12 ++++++------ docs/2.24.1/installation/index.html | 12 ++++++------ docs/2.24.1/internationalization/index.html | 12 ++++++------ docs/2.24.1/joanie-connection/index.html | 10 +++++----- docs/2.24.1/lms-backends/index.html | 10 +++++----- docs/2.24.1/lms-connection/index.html | 12 ++++++------ docs/2.24.1/native-installation/index.html | 12 ++++++------ docs/2.24.1/synchronizing-course-runs/index.html | 10 +++++----- docs/2.24.1/tls-connection/index.html | 10 +++++----- docs/2.24.1/web-analytics/index.html | 12 ++++++------ docs/2.25.0-beta.0/accessibility-testing/index.html | 12 ++++++------ .../api/course-run-synchronization-api/index.html | 10 +++++----- docs/2.25.0-beta.0/building-the-frontend/index.html | 12 ++++++------ docs/2.25.0-beta.0/contributing-guide/index.html | 12 ++++++------ docs/2.25.0-beta.0/cookiecutter/index.html | 12 ++++++------ docs/2.25.0-beta.0/css-guidelines/index.html | 12 ++++++------ docs/2.25.0-beta.0/discover/index.html | 12 ++++++------ .../displaying-connection-status/index.html | 10 +++++----- docs/2.25.0-beta.0/django-react-interop/index.html | 12 ++++++------ docs/2.25.0-beta.0/docker-development/index.html | 12 ++++++------ docs/2.25.0-beta.0/filters-customization/index.html | 12 ++++++------ docs/2.25.0-beta.0/frontend-overrides/index.html | 12 ++++++------ docs/2.25.0-beta.0/installation/index.html | 12 ++++++------ docs/2.25.0-beta.0/internationalization/index.html | 12 ++++++------ docs/2.25.0-beta.0/joanie-connection/index.html | 10 +++++----- docs/2.25.0-beta.0/lms-backends/index.html | 10 +++++----- docs/2.25.0-beta.0/lms-connection/index.html | 12 ++++++------ docs/2.25.0-beta.0/native-installation/index.html | 12 ++++++------ .../synchronizing-course-runs/index.html | 10 +++++----- docs/2.25.0-beta.0/tls-connection/index.html | 10 +++++----- docs/2.25.0-beta.0/web-analytics/index.html | 12 ++++++------ docs/2.25.0-beta.1/accessibility-testing/index.html | 12 ++++++------ .../api/course-run-synchronization-api/index.html | 10 +++++----- docs/2.25.0-beta.1/building-the-frontend/index.html | 12 ++++++------ docs/2.25.0-beta.1/contributing-guide/index.html | 12 ++++++------ docs/2.25.0-beta.1/cookiecutter/index.html | 12 ++++++------ docs/2.25.0-beta.1/css-guidelines/index.html | 12 ++++++------ docs/2.25.0-beta.1/discover/index.html | 12 ++++++------ .../displaying-connection-status/index.html | 10 +++++----- docs/2.25.0-beta.1/django-react-interop/index.html | 12 ++++++------ docs/2.25.0-beta.1/docker-development/index.html | 12 ++++++------ docs/2.25.0-beta.1/filters-customization/index.html | 12 ++++++------ docs/2.25.0-beta.1/frontend-overrides/index.html | 12 ++++++------ docs/2.25.0-beta.1/installation/index.html | 12 ++++++------ docs/2.25.0-beta.1/internationalization/index.html | 12 ++++++------ docs/2.25.0-beta.1/joanie-connection/index.html | 10 +++++----- docs/2.25.0-beta.1/lms-backends/index.html | 10 +++++----- docs/2.25.0-beta.1/lms-connection/index.html | 12 ++++++------ docs/2.25.0-beta.1/native-installation/index.html | 12 ++++++------ .../synchronizing-course-runs/index.html | 10 +++++----- docs/2.25.0-beta.1/tls-connection/index.html | 10 +++++----- docs/2.25.0-beta.1/web-analytics/index.html | 12 ++++++------ docs/2.3.0/accessibility-testing/index.html | 12 ++++++------ docs/2.3.0/building-the-frontend/index.html | 12 ++++++------ docs/2.3.0/contributing-guide/index.html | 12 ++++++------ docs/2.3.0/css-guidelines/index.html | 12 ++++++------ docs/2.3.0/discover/index.html | 12 ++++++------ docs/2.3.0/django-react-interop/index.html | 12 ++++++------ docs/2.3.0/docker-development/index.html | 12 ++++++------ docs/2.3.0/frontend-overrides/index.html | 12 ++++++------ docs/2.3.0/internationalization/index.html | 12 ++++++------ docs/2.3.0/lms-connection/index.html | 12 ++++++------ docs/2.3.0/native-installation/index.html | 12 ++++++------ docs/2.3.1/accessibility-testing/index.html | 12 ++++++------ docs/2.3.1/building-the-frontend/index.html | 12 ++++++------ docs/2.3.1/contributing-guide/index.html | 12 ++++++------ docs/2.3.1/css-guidelines/index.html | 12 ++++++------ docs/2.3.1/discover/index.html | 12 ++++++------ docs/2.3.1/django-react-interop/index.html | 12 ++++++------ docs/2.3.1/docker-development/index.html | 12 ++++++------ docs/2.3.1/frontend-overrides/index.html | 12 ++++++------ docs/2.3.1/internationalization/index.html | 12 ++++++------ docs/2.3.1/lms-connection/index.html | 12 ++++++------ docs/2.3.1/native-installation/index.html | 12 ++++++------ docs/2.3.2/accessibility-testing/index.html | 12 ++++++------ docs/2.3.2/building-the-frontend/index.html | 12 ++++++------ docs/2.3.2/contributing-guide/index.html | 12 ++++++------ docs/2.3.2/css-guidelines/index.html | 12 ++++++------ docs/2.3.2/discover/index.html | 12 ++++++------ docs/2.3.2/django-react-interop/index.html | 12 ++++++------ docs/2.3.2/docker-development/index.html | 12 ++++++------ docs/2.3.2/frontend-overrides/index.html | 12 ++++++------ docs/2.3.2/internationalization/index.html | 12 ++++++------ docs/2.3.2/lms-connection/index.html | 12 ++++++------ docs/2.3.2/native-installation/index.html | 12 ++++++------ docs/2.3.3/accessibility-testing/index.html | 12 ++++++------ docs/2.3.3/building-the-frontend/index.html | 12 ++++++------ docs/2.3.3/contributing-guide/index.html | 12 ++++++------ docs/2.3.3/css-guidelines/index.html | 12 ++++++------ docs/2.3.3/discover/index.html | 12 ++++++------ docs/2.3.3/django-react-interop/index.html | 12 ++++++------ docs/2.3.3/docker-development/index.html | 12 ++++++------ docs/2.3.3/frontend-overrides/index.html | 12 ++++++------ docs/2.3.3/internationalization/index.html | 12 ++++++------ docs/2.3.3/lms-connection/index.html | 12 ++++++------ docs/2.3.3/native-installation/index.html | 12 ++++++------ docs/2.4.0/accessibility-testing/index.html | 12 ++++++------ docs/2.4.0/building-the-frontend/index.html | 12 ++++++------ docs/2.4.0/contributing-guide/index.html | 12 ++++++------ docs/2.4.0/css-guidelines/index.html | 12 ++++++------ docs/2.4.0/discover/index.html | 12 ++++++------ docs/2.4.0/django-react-interop/index.html | 12 ++++++------ docs/2.4.0/docker-development/index.html | 12 ++++++------ docs/2.4.0/frontend-overrides/index.html | 12 ++++++------ docs/2.4.0/internationalization/index.html | 12 ++++++------ docs/2.4.0/lms-connection/index.html | 12 ++++++------ docs/2.4.0/native-installation/index.html | 12 ++++++------ docs/2.5.0/accessibility-testing/index.html | 12 ++++++------ docs/2.5.0/building-the-frontend/index.html | 12 ++++++------ docs/2.5.0/contributing-guide/index.html | 12 ++++++------ docs/2.5.0/css-guidelines/index.html | 12 ++++++------ docs/2.5.0/discover/index.html | 12 ++++++------ docs/2.5.0/django-react-interop/index.html | 12 ++++++------ docs/2.5.0/docker-development/index.html | 12 ++++++------ docs/2.5.0/frontend-overrides/index.html | 12 ++++++------ docs/2.5.0/internationalization/index.html | 12 ++++++------ docs/2.5.0/lms-connection/index.html | 12 ++++++------ docs/2.5.0/native-installation/index.html | 12 ++++++------ docs/2.6.0/accessibility-testing/index.html | 12 ++++++------ docs/2.6.0/building-the-frontend/index.html | 12 ++++++------ docs/2.6.0/contributing-guide/index.html | 12 ++++++------ docs/2.6.0/css-guidelines/index.html | 12 ++++++------ docs/2.6.0/discover/index.html | 12 ++++++------ docs/2.6.0/django-react-interop/index.html | 12 ++++++------ docs/2.6.0/docker-development/index.html | 12 ++++++------ docs/2.6.0/frontend-overrides/index.html | 12 ++++++------ docs/2.6.0/internationalization/index.html | 12 ++++++------ docs/2.6.0/lms-connection/index.html | 12 ++++++------ docs/2.6.0/native-installation/index.html | 12 ++++++------ docs/2.7.0/accessibility-testing/index.html | 12 ++++++------ docs/2.7.0/building-the-frontend/index.html | 12 ++++++------ docs/2.7.0/contributing-guide/index.html | 12 ++++++------ docs/2.7.0/css-guidelines/index.html | 12 ++++++------ docs/2.7.0/discover/index.html | 12 ++++++------ docs/2.7.0/django-react-interop/index.html | 12 ++++++------ docs/2.7.0/docker-development/index.html | 12 ++++++------ docs/2.7.0/frontend-overrides/index.html | 12 ++++++------ docs/2.7.0/internationalization/index.html | 12 ++++++------ docs/2.7.0/lms-connection/index.html | 12 ++++++------ docs/2.7.0/native-installation/index.html | 12 ++++++------ docs/2.7.1/accessibility-testing/index.html | 12 ++++++------ docs/2.7.1/building-the-frontend/index.html | 12 ++++++------ docs/2.7.1/contributing-guide/index.html | 12 ++++++------ docs/2.7.1/css-guidelines/index.html | 12 ++++++------ docs/2.7.1/discover/index.html | 12 ++++++------ docs/2.7.1/django-react-interop/index.html | 12 ++++++------ docs/2.7.1/docker-development/index.html | 12 ++++++------ docs/2.7.1/frontend-overrides/index.html | 12 ++++++------ docs/2.7.1/internationalization/index.html | 12 ++++++------ docs/2.7.1/lms-connection/index.html | 12 ++++++------ docs/2.7.1/native-installation/index.html | 12 ++++++------ docs/2.8.0/accessibility-testing/index.html | 12 ++++++------ .../api/course-run-synchronization-api/index.html | 10 +++++----- docs/2.8.0/building-the-frontend/index.html | 12 ++++++------ docs/2.8.0/contributing-guide/index.html | 12 ++++++------ docs/2.8.0/css-guidelines/index.html | 12 ++++++------ docs/2.8.0/discover/index.html | 12 ++++++------ docs/2.8.0/displaying-connection-status/index.html | 10 +++++----- docs/2.8.0/django-react-interop/index.html | 12 ++++++------ docs/2.8.0/docker-development/index.html | 12 ++++++------ docs/2.8.0/frontend-overrides/index.html | 12 ++++++------ docs/2.8.0/internationalization/index.html | 12 ++++++------ docs/2.8.0/lms-backends/index.html | 10 +++++----- docs/2.8.0/lms-connection/index.html | 12 ++++++------ docs/2.8.0/native-installation/index.html | 12 ++++++------ docs/2.8.0/synchronizing-course-runs/index.html | 10 +++++----- docs/2.8.0/tls-connection/index.html | 10 +++++----- docs/2.8.0/web-analytics/index.html | 10 +++++----- docs/2.8.1/accessibility-testing/index.html | 12 ++++++------ .../api/course-run-synchronization-api/index.html | 10 +++++----- docs/2.8.1/building-the-frontend/index.html | 12 ++++++------ docs/2.8.1/contributing-guide/index.html | 12 ++++++------ docs/2.8.1/css-guidelines/index.html | 12 ++++++------ docs/2.8.1/discover/index.html | 12 ++++++------ docs/2.8.1/displaying-connection-status/index.html | 10 +++++----- docs/2.8.1/django-react-interop/index.html | 12 ++++++------ docs/2.8.1/docker-development/index.html | 12 ++++++------ docs/2.8.1/frontend-overrides/index.html | 12 ++++++------ docs/2.8.1/internationalization/index.html | 12 ++++++------ docs/2.8.1/lms-backends/index.html | 10 +++++----- docs/2.8.1/lms-connection/index.html | 12 ++++++------ docs/2.8.1/native-installation/index.html | 12 ++++++------ docs/2.8.1/synchronizing-course-runs/index.html | 10 +++++----- docs/2.8.1/tls-connection/index.html | 10 +++++----- docs/2.8.1/web-analytics/index.html | 12 ++++++------ docs/2.8.2/accessibility-testing/index.html | 12 ++++++------ .../api/course-run-synchronization-api/index.html | 10 +++++----- docs/2.8.2/building-the-frontend/index.html | 12 ++++++------ docs/2.8.2/contributing-guide/index.html | 12 ++++++------ docs/2.8.2/css-guidelines/index.html | 12 ++++++------ docs/2.8.2/discover/index.html | 12 ++++++------ docs/2.8.2/displaying-connection-status/index.html | 10 +++++----- docs/2.8.2/django-react-interop/index.html | 12 ++++++------ docs/2.8.2/docker-development/index.html | 12 ++++++------ docs/2.8.2/frontend-overrides/index.html | 12 ++++++------ docs/2.8.2/internationalization/index.html | 12 ++++++------ docs/2.8.2/lms-backends/index.html | 10 +++++----- docs/2.8.2/lms-connection/index.html | 12 ++++++------ docs/2.8.2/native-installation/index.html | 12 ++++++------ docs/2.8.2/synchronizing-course-runs/index.html | 10 +++++----- docs/2.8.2/tls-connection/index.html | 10 +++++----- docs/2.8.2/web-analytics/index.html | 12 ++++++------ docs/2.9.0/accessibility-testing/index.html | 12 ++++++------ .../api/course-run-synchronization-api/index.html | 10 +++++----- docs/2.9.0/building-the-frontend/index.html | 12 ++++++------ docs/2.9.0/contributing-guide/index.html | 12 ++++++------ docs/2.9.0/css-guidelines/index.html | 12 ++++++------ docs/2.9.0/discover/index.html | 12 ++++++------ docs/2.9.0/displaying-connection-status/index.html | 10 +++++----- docs/2.9.0/django-react-interop/index.html | 12 ++++++------ docs/2.9.0/docker-development/index.html | 12 ++++++------ docs/2.9.0/frontend-overrides/index.html | 12 ++++++------ docs/2.9.0/internationalization/index.html | 12 ++++++------ docs/2.9.0/lms-backends/index.html | 10 +++++----- docs/2.9.0/lms-connection/index.html | 12 ++++++------ docs/2.9.0/native-installation/index.html | 12 ++++++------ docs/2.9.0/synchronizing-course-runs/index.html | 10 +++++----- docs/2.9.0/tls-connection/index.html | 10 +++++----- docs/2.9.0/web-analytics/index.html | 12 ++++++------ docs/2.9.1/accessibility-testing/index.html | 12 ++++++------ .../api/course-run-synchronization-api/index.html | 10 +++++----- docs/2.9.1/building-the-frontend/index.html | 12 ++++++------ docs/2.9.1/contributing-guide/index.html | 12 ++++++------ docs/2.9.1/css-guidelines/index.html | 12 ++++++------ docs/2.9.1/discover/index.html | 12 ++++++------ docs/2.9.1/displaying-connection-status/index.html | 10 +++++----- docs/2.9.1/django-react-interop/index.html | 12 ++++++------ docs/2.9.1/docker-development/index.html | 12 ++++++------ docs/2.9.1/frontend-overrides/index.html | 12 ++++++------ docs/2.9.1/internationalization/index.html | 12 ++++++------ docs/2.9.1/lms-backends/index.html | 10 +++++----- docs/2.9.1/lms-connection/index.html | 12 ++++++------ docs/2.9.1/native-installation/index.html | 12 ++++++------ docs/2.9.1/synchronizing-course-runs/index.html | 10 +++++----- docs/2.9.1/tls-connection/index.html | 10 +++++----- docs/2.9.1/web-analytics/index.html | 12 ++++++------ docs/accessibility-testing/index.html | 12 ++++++------ docs/api/course-run-synchronization-api/index.html | 10 +++++----- docs/building-the-frontend/index.html | 12 ++++++------ docs/contributing-guide/index.html | 12 ++++++------ docs/cookiecutter/index.html | 12 ++++++------ docs/css-guidelines/index.html | 12 ++++++------ docs/discover/index.html | 12 ++++++------ docs/displaying-connection-status/index.html | 10 +++++----- docs/django-react-interop/index.html | 12 ++++++------ docs/docker-development/index.html | 12 ++++++------ docs/filters-customization/index.html | 12 ++++++------ docs/frontend-overrides/index.html | 12 ++++++------ docs/installation/index.html | 12 ++++++------ docs/internationalization/index.html | 12 ++++++------ docs/joanie-connection/index.html | 10 +++++----- docs/lms-backends/index.html | 10 +++++----- docs/lms-connection/index.html | 12 ++++++------ docs/native-installation/index.html | 12 ++++++------ docs/next/accessibility-testing/index.html | 12 ++++++------ .../api/course-run-synchronization-api/index.html | 10 +++++----- docs/next/building-the-frontend/index.html | 12 ++++++------ docs/next/contributing-guide/index.html | 12 ++++++------ docs/next/cookiecutter/index.html | 12 ++++++------ docs/next/css-guidelines/index.html | 12 ++++++------ docs/next/discover/index.html | 12 ++++++------ docs/next/displaying-connection-status/index.html | 10 +++++----- docs/next/django-react-interop/index.html | 12 ++++++------ docs/next/docker-development/index.html | 12 ++++++------ docs/next/filters-customization/index.html | 12 ++++++------ docs/next/frontend-overrides/index.html | 12 ++++++------ docs/next/installation/index.html | 12 ++++++------ docs/next/internationalization/index.html | 12 ++++++------ docs/next/joanie-connection/index.html | 10 +++++----- docs/next/lms-backends/index.html | 10 +++++----- docs/next/lms-connection/index.html | 12 ++++++------ docs/next/native-installation/index.html | 12 ++++++------ docs/next/synchronizing-course-runs/index.html | 10 +++++----- docs/next/tls-connection/index.html | 10 +++++----- docs/next/web-analytics/index.html | 12 ++++++------ docs/synchronizing-course-runs/index.html | 10 +++++----- docs/tls-connection/index.html | 10 +++++----- docs/web-analytics/index.html | 12 ++++++------ help/index.html | 8 ++++---- index.html | 8 ++++---- users/index.html | 8 ++++---- versions/index.html | 8 ++++---- 2230 files changed, 5092 insertions(+), 5092 deletions(-) rename assets/css/{styles.bc5d7c07.css => styles.c29f85f3.css} (98%) create mode 100644 assets/js/000b5b65.7843b4ce.js delete mode 100644 assets/js/000b5b65.b1fe522f.js delete mode 100644 assets/js/00936db6.43128f3e.js create mode 100644 assets/js/00936db6.fa95273e.js create mode 100644 assets/js/00a73d6c.1fe4d188.js delete mode 100644 assets/js/00a73d6c.dbe2ecca.js create mode 100644 assets/js/0282d9da.39cf5b70.js delete mode 100644 assets/js/0282d9da.8043f81c.js rename assets/js/{2f1db623.d8badd5c.js => 0293ad88.eb8399b8.js} (56%) delete mode 100644 assets/js/0293ad88.fff4af89.js create mode 100644 assets/js/02a6e85d.d4fafaee.js delete mode 100644 assets/js/02a6e85d.d7aeadaa.js create mode 100644 assets/js/02aff391.0126c97b.js delete mode 100644 assets/js/02aff391.34c4176e.js delete mode 100644 assets/js/02fbc50f.06a2e257.js create mode 100644 assets/js/02fbc50f.9f114b36.js delete mode 100644 assets/js/0386b2c0.26f5414a.js create mode 100644 assets/js/0386b2c0.49fc2b6a.js create mode 100644 assets/js/03a6f5b2.92d59349.js delete mode 100644 assets/js/03a6f5b2.e2306470.js create mode 100644 assets/js/03e22855.0b6f1028.js delete mode 100644 assets/js/03e22855.5db721db.js create mode 100644 assets/js/03e479ab.13f98885.js delete mode 100644 assets/js/03e479ab.c258e004.js delete mode 100644 assets/js/05054f56.65f6d618.js create mode 100644 assets/js/05054f56.79ea3f6b.js create mode 100644 assets/js/05adccc0.3f338ef6.js delete mode 100644 assets/js/05adccc0.f2de587c.js delete mode 100644 assets/js/061b9ec0.8578e0c1.js create mode 100644 assets/js/061b9ec0.bba32130.js delete mode 100644 assets/js/06447dd5.3f895c02.js create mode 100644 assets/js/06447dd5.6cf6e11d.js create mode 100644 assets/js/06bcdf26.1d5f8354.js delete mode 100644 assets/js/06bcdf26.d190b60e.js delete mode 100644 assets/js/06e6648e.0cbd1b43.js create mode 100644 assets/js/06e6648e.52069984.js delete mode 100644 assets/js/07ba485a.5951a251.js create mode 100644 assets/js/07ba485a.ff70a59c.js delete mode 100644 assets/js/07dcad66.3f781cbb.js create mode 100644 assets/js/07dcad66.ddf2d91a.js create mode 100644 assets/js/07f167f3.3765bd72.js delete mode 100644 assets/js/07f167f3.970290a6.js create mode 100644 assets/js/08cf9976.47182207.js delete mode 100644 assets/js/08cf9976.9f4d3dff.js delete mode 100644 assets/js/08d8a2f4.5d27a0f5.js create mode 100644 assets/js/08d8a2f4.6abb478b.js create mode 100644 assets/js/096f38f4.5e79698a.js delete mode 100644 assets/js/096f38f4.a5315ca4.js delete mode 100644 assets/js/097ac4c7.9fa3e729.js create mode 100644 assets/js/097ac4c7.addccb10.js delete mode 100644 assets/js/0994b750.25a6e89e.js create mode 100644 assets/js/0994b750.47049489.js delete mode 100644 assets/js/099fd313.a308f218.js create mode 100644 assets/js/099fd313.c99f6cff.js create mode 100644 assets/js/09dbdf3a.2f79efdb.js delete mode 100644 assets/js/09dbdf3a.677e47cf.js delete mode 100644 assets/js/09f8bc84.281c6ff0.js create mode 100644 assets/js/09f8bc84.c97c3b99.js create mode 100644 assets/js/09fcd96a.76580d58.js delete mode 100644 assets/js/09fcd96a.a3e897b9.js delete mode 100644 assets/js/0add6094.6e6ebca3.js create mode 100644 assets/js/0add6094.faffc24e.js create mode 100644 assets/js/0ae680de.25a0920e.js create mode 100644 assets/js/0b14c283.2dadbf41.js delete mode 100644 assets/js/0b14c283.7de4cdaa.js delete mode 100644 assets/js/0b704f48.125b280b.js create mode 100644 assets/js/0b704f48.9d9cb121.js delete mode 100644 assets/js/0b7302f4.ab68a346.js create mode 100644 assets/js/0b7302f4.d7b06e14.js create mode 100644 assets/js/0c537762.9ae5486a.js delete mode 100644 assets/js/0c537762.abc38d88.js delete mode 100644 assets/js/0c6c321c.ebc66fa9.js create mode 100644 assets/js/0c6c321c.ff7c58ea.js delete mode 100644 assets/js/0ce075bd.6e1439e3.js create mode 100644 assets/js/0ce075bd.6eabb8db.js create mode 100644 assets/js/0d621e61.d46e5536.js delete mode 100644 assets/js/0d621e61.ef268db2.js delete mode 100644 assets/js/0db3065d.7cbbe3b3.js create mode 100644 assets/js/0db3065d.f1417ff0.js create mode 100644 assets/js/0e19e8fc.7946f3b9.js delete mode 100644 assets/js/0e19e8fc.fe814962.js create mode 100644 assets/js/0e83f9e9.d9927db6.js delete mode 100644 assets/js/0e83f9e9.eda23db6.js create mode 100644 assets/js/0ea4a466.92361403.js delete mode 100644 assets/js/0ea4a466.dcc084d5.js create mode 100644 assets/js/0f3a7c54.c55c081e.js delete mode 100644 assets/js/0f3a7c54.cc630390.js create mode 100644 assets/js/0f431cec.da780187.js delete mode 100644 assets/js/0f431cec.eef7aad1.js delete mode 100644 assets/js/0f6d1c6c.bff09f92.js create mode 100644 assets/js/0f6d1c6c.f0e1a802.js delete mode 100644 assets/js/0fc2919f.5e5ec8a4.js create mode 100644 assets/js/0fc2919f.73dfb141.js create mode 100644 assets/js/103b72cd.88c8709c.js delete mode 100644 assets/js/103b72cd.ba57cf7c.js create mode 100644 assets/js/1050eb4f.2e6d816c.js delete mode 100644 assets/js/1050eb4f.a140a676.js delete mode 100644 assets/js/1053756e.75139f1c.js create mode 100644 assets/js/1053756e.91d50c35.js create mode 100644 assets/js/10a40cfc.16b7773d.js delete mode 100644 assets/js/10a40cfc.75486736.js delete mode 100644 assets/js/10fdb3ce.90ecd733.js create mode 100644 assets/js/10fdb3ce.b20e20e9.js delete mode 100644 assets/js/112db83c.3771fe56.js rename assets/js/{4acc282a.4a69cad6.js => 112db83c.64e15de5.js} (95%) create mode 100644 assets/js/11415922.a91a1311.js create mode 100644 assets/js/11f70aa8.810e75ee.js delete mode 100644 assets/js/11f70aa8.af41768c.js delete mode 100644 assets/js/127c2ea3.f1d5f84d.js create mode 100644 assets/js/127c2ea3.f35d79f7.js create mode 100644 assets/js/127f66d4.90a8f98f.js delete mode 100644 assets/js/127f66d4.a26d6c91.js create mode 100644 assets/js/136c1d54.6df5d49f.js delete mode 100644 assets/js/136c1d54.a72b4a9d.js delete mode 100644 assets/js/13c51ea3.0c46cb2d.js create mode 100644 assets/js/13c51ea3.18e83337.js delete mode 100644 assets/js/13f7722f.83195828.js create mode 100644 assets/js/13f7722f.88286c29.js rename assets/js/{3e42226b.eb8e97ad.js => 14e5e79f.3e19f51d.js} (62%) delete mode 100644 assets/js/14e5e79f.ed07131b.js create mode 100644 assets/js/14f618b0.8a8e5aa6.js delete mode 100644 assets/js/14f618b0.c078db23.js create mode 100644 assets/js/15106207.77740055.js delete mode 100644 assets/js/15106207.8221626e.js create mode 100644 assets/js/164a50fb.0b4e2a86.js delete mode 100644 assets/js/164a50fb.f976d84a.js create mode 100644 assets/js/1681c897.7e1771c5.js delete mode 100644 assets/js/1681c897.e909a8c7.js create mode 100644 assets/js/168235c0.1ddb7c5e.js delete mode 100644 assets/js/168235c0.d25627ce.js create mode 100644 assets/js/171addfa.1b9e2c9a.js delete mode 100644 assets/js/171addfa.9b35e9b5.js create mode 100644 assets/js/172cef5d.5880b1be.js delete mode 100644 assets/js/17896441.028fad21.js create mode 100644 assets/js/17896441.0f4ea831.js create mode 100644 assets/js/17fa148f.00d8e94c.js delete mode 100644 assets/js/17fa148f.079939ef.js delete mode 100644 assets/js/1818bfeb.597d9670.js create mode 100644 assets/js/1818bfeb.8d4ee9ef.js delete mode 100644 assets/js/187597a1.7c33e5f0.js create mode 100644 assets/js/187597a1.c3085446.js create mode 100644 assets/js/18c55237.69ecc1d4.js delete mode 100644 assets/js/18c55237.f3ae7594.js delete mode 100644 assets/js/18c7e6dd.22c58d97.js rename assets/js/{e23da508.a0c4ef40.js => 18c7e6dd.7f6cc03c.js} (60%) create mode 100644 assets/js/18ec690c.0560c7b4.js delete mode 100644 assets/js/18ec690c.0f6d7606.js delete mode 100644 assets/js/19030215.8396b107.js create mode 100644 assets/js/19030215.c4a9fa62.js create mode 100644 assets/js/19099ebb.a71d3901.js delete mode 100644 assets/js/1988e61b.02de9c41.js create mode 100644 assets/js/1988e61b.f83c3fa6.js create mode 100644 assets/js/19b30c77.62741dd6.js delete mode 100644 assets/js/19b30c77.e4ff61dc.js delete mode 100644 assets/js/1b0422f0.5d47abb3.js create mode 100644 assets/js/1b0422f0.73ddfa1e.js create mode 100644 assets/js/1b22849d.ee9c7835.js delete mode 100644 assets/js/1b22849d.f753b463.js delete mode 100644 assets/js/1b340b9f.07dee382.js create mode 100644 assets/js/1b340b9f.6f53b7b0.js create mode 100644 assets/js/1c5e7615.6ed4e74e.js delete mode 100644 assets/js/1c5e7615.ba9f8011.js delete mode 100644 assets/js/1caa6db9.49cd54a0.js create mode 100644 assets/js/1caa6db9.f77932b6.js delete mode 100644 assets/js/1cf6e8ef.610fab07.js create mode 100644 assets/js/1cf6e8ef.7857b656.js delete mode 100644 assets/js/1d06aaab.a00fbe8a.js create mode 100644 assets/js/1d06aaab.f2f8d4cb.js create mode 100644 assets/js/1d2426fc.77fd1c1a.js create mode 100644 assets/js/1da01b0f.a3946776.js delete mode 100644 assets/js/1da01b0f.d0f66a71.js create mode 100644 assets/js/1daa9480.13b40286.js delete mode 100644 assets/js/1daa9480.d5dc103e.js delete mode 100644 assets/js/1dd9b9f1.786aa2ae.js create mode 100644 assets/js/1dd9b9f1.7f5e74dd.js create mode 100644 assets/js/1e1fe148.0b9a59ca.js delete mode 100644 assets/js/1e1fe148.af671901.js delete mode 100644 assets/js/1e33be1c.3bf4c671.js create mode 100644 assets/js/1e33be1c.e869702f.js create mode 100644 assets/js/1e38d8f6.3c21f419.js delete mode 100644 assets/js/1e38d8f6.cc18e34d.js delete mode 100644 assets/js/1f7fcbb7.14eb1f4b.js create mode 100644 assets/js/1f7fcbb7.2a0c5483.js create mode 100644 assets/js/1f910db0.3a2c8f08.js delete mode 100644 assets/js/1f910db0.5553b1bb.js create mode 100644 assets/js/1fafbf27.424ebb48.js delete mode 100644 assets/js/1fafbf27.cefabd30.js create mode 100644 assets/js/2016fde8.47e7a98f.js delete mode 100644 assets/js/2016fde8.63fd4761.js create mode 100644 assets/js/201fa7d6.0a7f64e9.js delete mode 100644 assets/js/201fa7d6.eacf7af9.js delete mode 100644 assets/js/20375412.6753cf29.js create mode 100644 assets/js/20375412.c180f4ea.js create mode 100644 assets/js/208b3683.2def0e96.js delete mode 100644 assets/js/208b3683.624000eb.js delete mode 100644 assets/js/209f9d96.2908ee72.js create mode 100644 assets/js/209f9d96.62e294db.js create mode 100644 assets/js/20c8a971.5a979e77.js create mode 100644 assets/js/20c9ae5c.65d32fde.js delete mode 100644 assets/js/20c9ae5c.80c18adf.js create mode 100644 assets/js/20de91ac.11599b79.js delete mode 100644 assets/js/20de91ac.34992e2c.js create mode 100644 assets/js/20ded4b9.d5eec564.js delete mode 100644 assets/js/20ded4b9.df5646e2.js create mode 100644 assets/js/20e1c70d.41277a89.js delete mode 100644 assets/js/20e1c70d.7c864bdb.js create mode 100644 assets/js/211a457e.8d860d98.js delete mode 100644 assets/js/211a457e.e9b01723.js create mode 100644 assets/js/216f1911.9fa91641.js delete mode 100644 assets/js/216f1911.bbb2e1ad.js create mode 100644 assets/js/225aacf5.90345b3c.js delete mode 100644 assets/js/225aacf5.f9938e43.js create mode 100644 assets/js/23012ccd.44d6744b.js delete mode 100644 assets/js/23012ccd.e0afde49.js delete mode 100644 assets/js/238b593d.282969ff.js create mode 100644 assets/js/238b593d.aa15f2ae.js delete mode 100644 assets/js/2392e8d5.8ae29191.js create mode 100644 assets/js/2392e8d5.def65ee5.js delete mode 100644 assets/js/23f4de98.821bb624.js create mode 100644 assets/js/23f4de98.90a0206d.js delete mode 100644 assets/js/2411f77f.3baf3d1c.js create mode 100644 assets/js/2411f77f.48eb3be1.js create mode 100644 assets/js/24ce56fa.67a170e3.js delete mode 100644 assets/js/24ce56fa.e7322eac.js create mode 100644 assets/js/251cb658.7ce61fc7.js delete mode 100644 assets/js/251cb658.d92a4e3d.js create mode 100644 assets/js/254587dc.57d98d87.js delete mode 100644 assets/js/254587dc.96f96f5e.js rename assets/js/{27cd943b.7f7595dd.js => 254ad699.18617fab.js} (81%) delete mode 100644 assets/js/254ad699.c25fb9d8.js delete mode 100644 assets/js/254f523d.014e2d34.js create mode 100644 assets/js/254f523d.81f275bd.js rename assets/js/{447f82ad.fee22db6.js => 2682d1a6.3ac7e4cd.js} (89%) delete mode 100644 assets/js/2682d1a6.90f87f09.js delete mode 100644 assets/js/26e576cc.2eb9e86d.js create mode 100644 assets/js/26e576cc.65415403.js create mode 100644 assets/js/27461c5b.450d7bd7.js delete mode 100644 assets/js/27461c5b.eb9e2dbe.js create mode 100644 assets/js/276b156f.a8424219.js delete mode 100644 assets/js/276b156f.d48b2f25.js delete mode 100644 assets/js/278477af.7dc9f137.js create mode 100644 assets/js/278477af.b40dfc54.js create mode 100644 assets/js/27cd943b.4c8bd45e.js create mode 100644 assets/js/28a7aef2.084954d3.js delete mode 100644 assets/js/28a7aef2.b30c88c9.js create mode 100644 assets/js/291741fc.6e588acd.js delete mode 100644 assets/js/291741fc.b843fa86.js create mode 100644 assets/js/2945dbfd.740d5eb6.js delete mode 100644 assets/js/2945dbfd.ae8724cc.js create mode 100644 assets/js/29a15cf5.35132d84.js delete mode 100644 assets/js/29a15cf5.3a254310.js delete mode 100644 assets/js/2aab0461.05ce33cc.js create mode 100644 assets/js/2aab0461.c4a3bef0.js create mode 100644 assets/js/2ad723ae.8e1ba04e.js delete mode 100644 assets/js/2ad723ae.b52b6f66.js create mode 100644 assets/js/2b0294df.250dd975.js delete mode 100644 assets/js/2b0294df.c8312699.js delete mode 100644 assets/js/2b0ea6a3.08a711c0.js create mode 100644 assets/js/2b0ea6a3.3f2c6d1a.js delete mode 100644 assets/js/2b603511.15ddc564.js create mode 100644 assets/js/2b603511.6de69622.js create mode 100644 assets/js/2bd76b34.8e151178.js delete mode 100644 assets/js/2bd76b34.adb22582.js create mode 100644 assets/js/2c72f107.5252ca4b.js delete mode 100644 assets/js/2c72f107.54cab9b5.js delete mode 100644 assets/js/2cb39df3.4ed9fa33.js create mode 100644 assets/js/2cb39df3.67ccf65d.js create mode 100644 assets/js/2cc95c91.70439a41.js delete mode 100644 assets/js/2cc95c91.72cfe0e4.js create mode 100644 assets/js/2ccae19e.160f0b50.js delete mode 100644 assets/js/2ccae19e.86a37cfb.js create mode 100644 assets/js/2dc75d44.c2124428.js delete mode 100644 assets/js/2dc75d44.f1d7f5bf.js create mode 100644 assets/js/2dd5feb9.5b7178d3.js delete mode 100644 assets/js/2dd5feb9.b3750dc3.js create mode 100644 assets/js/2eb4cc07.528ce82b.js delete mode 100644 assets/js/2eb4cc07.877a2862.js delete mode 100644 assets/js/2ef36261.bacf5085.js create mode 100644 assets/js/2ef36261.ef722f7c.js create mode 100644 assets/js/2f1db623.37c4382f.js create mode 100644 assets/js/2f83db41.31d0c7fb.js delete mode 100644 assets/js/2f83db41.c4367721.js create mode 100644 assets/js/2fbb3042.752272f6.js delete mode 100644 assets/js/2fbb3042.cc7c252a.js create mode 100644 assets/js/2fbc32c8.4330ee46.js delete mode 100644 assets/js/2fbc32c8.b23a92de.js delete mode 100644 assets/js/30bcdfaf.093e7389.js create mode 100644 assets/js/30bcdfaf.9007471e.js create mode 100644 assets/js/30d29c5d.42d64433.js delete mode 100644 assets/js/30d29c5d.933b5d75.js create mode 100644 assets/js/312a9924.3b800466.js delete mode 100644 assets/js/312a9924.56934f0d.js create mode 100644 assets/js/32315083.8fd79ff1.js delete mode 100644 assets/js/32315083.bf371d37.js create mode 100644 assets/js/32488265.47522df2.js delete mode 100644 assets/js/32488265.c592ff30.js delete mode 100644 assets/js/325a4da8.01193e3d.js create mode 100644 assets/js/325a4da8.8ce42c11.js delete mode 100644 assets/js/32c602fd.7dc7c8cf.js create mode 100644 assets/js/32c602fd.e29557bd.js delete mode 100644 assets/js/3311796b.41d66a37.js create mode 100644 assets/js/3311796b.8670fdd2.js delete mode 100644 assets/js/335c1f05.274bb590.js rename assets/js/{74dddc49.4d3bcba9.js => 335c1f05.a5ed56b4.js} (88%) create mode 100644 assets/js/33fbc32e.0a81c394.js delete mode 100644 assets/js/33fbc32e.61332f9e.js delete mode 100644 assets/js/34596675.54a193b0.js create mode 100644 assets/js/34596675.8c0b03b6.js create mode 100644 assets/js/34cb51de.a90aec9a.js delete mode 100644 assets/js/34ff41bb.631eaacf.js create mode 100644 assets/js/34ff41bb.7612486d.js delete mode 100644 assets/js/3545c428.130960b0.js create mode 100644 assets/js/3545c428.7c9974af.js delete mode 100644 assets/js/354f5663.17c92ee4.js create mode 100644 assets/js/354f5663.515bf474.js create mode 100644 assets/js/3585f5da.4f4d7a3c.js delete mode 100644 assets/js/3585f5da.73d01c44.js create mode 100644 assets/js/3673a8ce.6c8697ed.js delete mode 100644 assets/js/3673a8ce.ba714810.js create mode 100644 assets/js/3714cfae.c7932a1d.js delete mode 100644 assets/js/3714cfae.d0c80244.js delete mode 100644 assets/js/371d0026.f3fbf9d1.js rename assets/js/{172cef5d.57ad0a39.js => 371d0026.f87223a6.js} (93%) create mode 100644 assets/js/37273ca3.04fe3a3e.js delete mode 100644 assets/js/37273ca3.dc3d1494.js delete mode 100644 assets/js/378ee88a.05959ca7.js create mode 100644 assets/js/378ee88a.ad22836b.js delete mode 100644 assets/js/384badf6.9548c9f1.js create mode 100644 assets/js/384badf6.ca991f6d.js create mode 100644 assets/js/38896deb.1397ea04.js delete mode 100644 assets/js/38896deb.f0a0a117.js create mode 100644 assets/js/389c8989.039e42c7.js delete mode 100644 assets/js/389c8989.78f3e453.js create mode 100644 assets/js/38ae1160.526e0b87.js delete mode 100644 assets/js/38ae1160.fa79ecf0.js create mode 100644 assets/js/38c22082.08365f5d.js delete mode 100644 assets/js/38c22082.91c8c244.js create mode 100644 assets/js/395eb7c6.5b64e2d5.js delete mode 100644 assets/js/395eb7c6.e05ee302.js delete mode 100644 assets/js/39917643.ae75d537.js create mode 100644 assets/js/39917643.bf026dd3.js delete mode 100644 assets/js/3a0f357d.3e103301.js create mode 100644 assets/js/3a0f357d.ddf84d84.js create mode 100644 assets/js/3a5b4eed.270d442c.js delete mode 100644 assets/js/3a5b4eed.b15911cb.js create mode 100644 assets/js/3a6bbf33.292b96b4.js create mode 100644 assets/js/3a6f03ad.51fd014f.js delete mode 100644 assets/js/3a6f03ad.ea386127.js create mode 100644 assets/js/3b31280e.1952d591.js delete mode 100644 assets/js/3b31280e.37bb291e.js create mode 100644 assets/js/3bfd137c.a6927c11.js delete mode 100644 assets/js/3bfd137c.e2e73e15.js create mode 100644 assets/js/3c1a2d15.41f2e362.js delete mode 100644 assets/js/3c1a2d15.f429ea42.js create mode 100644 assets/js/3c1a997b.1cb76f74.js delete mode 100644 assets/js/3c1a997b.ffdd669f.js delete mode 100644 assets/js/3c775348.67d7740a.js create mode 100644 assets/js/3c775348.7785e1b0.js create mode 100644 assets/js/3c7d7aed.9f3ee25b.js create mode 100644 assets/js/3cc42aff.5ce2bd96.js delete mode 100644 assets/js/3cc42aff.ff0bba56.js delete mode 100644 assets/js/3d1f5df7.81608679.js create mode 100644 assets/js/3d1f5df7.b6209fa1.js delete mode 100644 assets/js/3dd7b968.567059ea.js create mode 100644 assets/js/3dd7b968.97caa4d0.js create mode 100644 assets/js/3de0f5e2.5cba7bde.js delete mode 100644 assets/js/3de0f5e2.8dd961a6.js create mode 100644 assets/js/3e0d2163.72af2d09.js delete mode 100644 assets/js/3e0d2163.a086c2e2.js create mode 100644 assets/js/3e42226b.0d4b11eb.js delete mode 100644 assets/js/3ea77f47.431dd660.js create mode 100644 assets/js/3ea77f47.b017db9c.js create mode 100644 assets/js/3fcfa83f.51d4027f.js delete mode 100644 assets/js/3fcfa83f.be3cb794.js create mode 100644 assets/js/3fd0faed.840b983c.js delete mode 100644 assets/js/3fd0faed.c4111eed.js create mode 100644 assets/js/4220d24c.d4310642.js delete mode 100644 assets/js/4220d24c.f0359c78.js delete mode 100644 assets/js/42e63d8f.9383f492.js create mode 100644 assets/js/42e63d8f.ea8f897d.js create mode 100644 assets/js/43dd260b.8e1b24bf.js delete mode 100644 assets/js/43dd260b.d2ce0297.js create mode 100644 assets/js/442e170d.8613aef2.js delete mode 100644 assets/js/442e170d.c33fb602.js create mode 100644 assets/js/447f82ad.25ad796b.js create mode 100644 assets/js/44b658dc.6dd07555.js delete mode 100644 assets/js/44b658dc.fbe037ed.js delete mode 100644 assets/js/451cc400.48b59541.js create mode 100644 assets/js/451cc400.b5180164.js delete mode 100644 assets/js/4538b3d3.453d6ab4.js create mode 100644 assets/js/4538b3d3.6f6839c8.js create mode 100644 assets/js/4567f559.7292cb07.js delete mode 100644 assets/js/4567f559.c6a298c2.js delete mode 100644 assets/js/45a39ade.b6ebef43.js create mode 100644 assets/js/45a39ade.bf37498b.js create mode 100644 assets/js/45fa8fc8.3621c2d3.js delete mode 100644 assets/js/45fa8fc8.f4c2f8c5.js delete mode 100644 assets/js/4610903a.85bcd810.js create mode 100644 assets/js/4610903a.e6aac95c.js delete mode 100644 assets/js/46651703.8f48696d.js create mode 100644 assets/js/46651703.dada904a.js create mode 100644 assets/js/46b63591.4cedb57c.js delete mode 100644 assets/js/46b63591.de4b1355.js create mode 100644 assets/js/47664efc.8bcf8052.js delete mode 100644 assets/js/47664efc.c3c8270e.js create mode 100644 assets/js/48393576.2e629f0d.js delete mode 100644 assets/js/48393576.bc594b37.js create mode 100644 assets/js/48b41b21.2c9a1190.js delete mode 100644 assets/js/48b41b21.7cf12bd2.js delete mode 100644 assets/js/491e3748.4ff3e082.js create mode 100644 assets/js/491e3748.6c0c8dde.js delete mode 100644 assets/js/49a3ff07.1f7f5aaa.js create mode 100644 assets/js/49a3ff07.711f5883.js delete mode 100644 assets/js/49c1aea8.c1ddc52e.js create mode 100644 assets/js/49c1aea8.cec05417.js create mode 100644 assets/js/49c28f3e.7ac4cf71.js delete mode 100644 assets/js/49c28f3e.f868b412.js delete mode 100644 assets/js/49c48079.7b77e0b8.js create mode 100644 assets/js/49c48079.86b9f69c.js delete mode 100644 assets/js/4a372eea.70759cc3.js create mode 100644 assets/js/4a372eea.9bb65e5b.js create mode 100644 assets/js/4a72972d.00279647.js delete mode 100644 assets/js/4a72972d.cae2251e.js create mode 100644 assets/js/4acc282a.1af063af.js create mode 100644 assets/js/4b3d2ce7.2e3a4f7d.js delete mode 100644 assets/js/4b3d2ce7.886060b2.js create mode 100644 assets/js/4bc32079.16d2ed76.js delete mode 100644 assets/js/4bc32079.7158e393.js delete mode 100644 assets/js/4cdff131.e2bf0707.js create mode 100644 assets/js/4cdff131.e58b7eed.js create mode 100644 assets/js/4cecff54.a807f016.js delete mode 100644 assets/js/4cecff54.c0dd006c.js create mode 100644 assets/js/4d48fcb7.7c664edb.js delete mode 100644 assets/js/4d48fcb7.c1246af6.js delete mode 100644 assets/js/4dba59ca.2994a3d8.js create mode 100644 assets/js/4dba59ca.c9379215.js delete mode 100644 assets/js/4dd6f7af.427f7494.js create mode 100644 assets/js/4dd6f7af.f2227789.js delete mode 100644 assets/js/4e278954.c7dae782.js create mode 100644 assets/js/4e278954.d707241f.js create mode 100644 assets/js/4e8f03cd.507058d0.js delete mode 100644 assets/js/4e8f03cd.c860a615.js create mode 100644 assets/js/4ea51cf7.11b2de1e.js delete mode 100644 assets/js/4ea51cf7.d495e1f1.js create mode 100644 assets/js/4ee76bca.f08ac328.js create mode 100644 assets/js/4f2fd236.ae9aaff4.js delete mode 100644 assets/js/4f2fd236.e40e2d57.js delete mode 100644 assets/js/4f59363e.88fef57d.js create mode 100644 assets/js/4f59363e.ab5bc414.js create mode 100644 assets/js/4feb6cd1.c7492b53.js delete mode 100644 assets/js/4feb6cd1.caac4977.js create mode 100644 assets/js/509ab375.66a99c27.js delete mode 100644 assets/js/509ab375.ead64830.js create mode 100644 assets/js/50f6977b.67d8e26f.js delete mode 100644 assets/js/50f6977b.8f223948.js create mode 100644 assets/js/51b39968.9b1d98cf.js delete mode 100644 assets/js/51b39968.f299113a.js create mode 100644 assets/js/51cf57e0.1b8f89dc.js delete mode 100644 assets/js/51cf57e0.b782c227.js delete mode 100644 assets/js/526a9c93.1b10d765.js create mode 100644 assets/js/526a9c93.5f7bf9f4.js create mode 100644 assets/js/52a67732.0a288ef1.js delete mode 100644 assets/js/52a67732.9b5e41e7.js create mode 100644 assets/js/53346373.f59e03d1.js create mode 100644 assets/js/53ae6633.d227b258.js delete mode 100644 assets/js/53ae6633.faa11e37.js delete mode 100644 assets/js/53eeef0b.2bca39df.js create mode 100644 assets/js/53eeef0b.e0114c41.js delete mode 100644 assets/js/546a9229.544d52d1.js create mode 100644 assets/js/546a9229.854acb31.js create mode 100644 assets/js/54e62810.05537c28.js delete mode 100644 assets/js/54e62810.67d1806c.js create mode 100644 assets/js/55ca2829.e290df63.js delete mode 100644 assets/js/55ca2829.f76385a4.js create mode 100644 assets/js/567b9119.5cdfc1e0.js delete mode 100644 assets/js/567b9119.6b742e66.js create mode 100644 assets/js/56d3718f.427da004.js delete mode 100644 assets/js/56d3718f.80f4b70b.js create mode 100644 assets/js/56f07039.765500fd.js delete mode 100644 assets/js/56f07039.cf34dcdd.js create mode 100644 assets/js/56f286e3.7b765b7d.js delete mode 100644 assets/js/56f286e3.83745087.js delete mode 100644 assets/js/570846ac.3a3ff9f9.js create mode 100644 assets/js/570846ac.e37364d6.js delete mode 100644 assets/js/5785daff.4831c765.js create mode 100644 assets/js/5785daff.a5456c80.js create mode 100644 assets/js/578a4822.1b11cf31.js delete mode 100644 assets/js/578a4822.8daf9a72.js delete mode 100644 assets/js/5801c226.642b38ea.js create mode 100644 assets/js/5801c226.75a49e22.js create mode 100644 assets/js/5882ca40.09c3a83e.js delete mode 100644 assets/js/5882ca40.53992464.js delete mode 100644 assets/js/58a4f9c4.c452149b.js create mode 100644 assets/js/58a4f9c4.d768bb7a.js create mode 100644 assets/js/58a95835.26c0966b.js delete mode 100644 assets/js/58a95835.9a7e0577.js create mode 100644 assets/js/598cf0cc.4f021386.js delete mode 100644 assets/js/598cf0cc.6808770b.js create mode 100644 assets/js/59a6ed9f.ca190933.js delete mode 100644 assets/js/59a6ed9f.f9ae4ac7.js create mode 100644 assets/js/5a72d50a.b820c0b7.js delete mode 100644 assets/js/5a72d50a.cc0e8df4.js create mode 100644 assets/js/5ab2e4c0.f49471e0.js create mode 100644 assets/js/5ad71dc2.68957121.js delete mode 100644 assets/js/5ad71dc2.71f5f4ac.js delete mode 100644 assets/js/5b1e20a2.31d06d8f.js create mode 100644 assets/js/5b1e20a2.d41b574b.js create mode 100644 assets/js/5c3859ae.89ed20b7.js delete mode 100644 assets/js/5c3859ae.d6435eaa.js create mode 100644 assets/js/5ce5f8b6.2197cedc.js delete mode 100644 assets/js/5ce5f8b6.453640c9.js create mode 100644 assets/js/5d5a7f04.0b64332d.js delete mode 100644 assets/js/5d5a7f04.639e35c2.js delete mode 100644 assets/js/5d5c5f94.beff32a9.js create mode 100644 assets/js/5d5c5f94.f8ff9e5a.js create mode 100644 assets/js/5dab2dcc.03daa588.js delete mode 100644 assets/js/5dab2dcc.2d3906bb.js delete mode 100644 assets/js/5dd64854.591acd39.js create mode 100644 assets/js/5dd64854.94b510e0.js create mode 100644 assets/js/5dd80f8d.252ea40f.js delete mode 100644 assets/js/5dd80f8d.ef5b2267.js create mode 100644 assets/js/5e1c13c1.725a83a9.js delete mode 100644 assets/js/5e1c13c1.af5ef71e.js create mode 100644 assets/js/5e662b40.504204f1.js delete mode 100644 assets/js/5e662b40.57ce37d1.js delete mode 100644 assets/js/5e71fbd6.788ad15a.js create mode 100644 assets/js/5e71fbd6.d425c011.js delete mode 100644 assets/js/5f0658da.0562c735.js create mode 100644 assets/js/5f0658da.be58f40d.js create mode 100644 assets/js/5f52e4de.3f7c4d4e.js delete mode 100644 assets/js/5f52e4de.64872f7e.js delete mode 100644 assets/js/5fee430a.1732644e.js create mode 100644 assets/js/5fee430a.a971530e.js delete mode 100644 assets/js/60092ac2.5f5e2153.js create mode 100644 assets/js/60092ac2.cb1b742c.js create mode 100644 assets/js/608122d4.513c83d3.js delete mode 100644 assets/js/608122d4.ef612457.js create mode 100644 assets/js/60813e77.3d66d983.js delete mode 100644 assets/js/60813e77.c0720148.js delete mode 100644 assets/js/615894c7.352766e1.js create mode 100644 assets/js/615894c7.c65023bf.js create mode 100644 assets/js/62001d57.5aeb8af1.js delete mode 100644 assets/js/62001d57.c96015b1.js create mode 100644 assets/js/6202e9b0.25734e4e.js delete mode 100644 assets/js/6202e9b0.d63dafb9.js delete mode 100644 assets/js/627191fc.20d9e81c.js create mode 100644 assets/js/627191fc.f9a6f7a4.js create mode 100644 assets/js/62770d20.5c835552.js delete mode 100644 assets/js/62770d20.d8fe7b6d.js create mode 100644 assets/js/6396a7fe.490d79d8.js delete mode 100644 assets/js/6396a7fe.61a31dcc.js create mode 100644 assets/js/63f503ba.358aa8cb.js delete mode 100644 assets/js/63f503ba.885e1353.js delete mode 100644 assets/js/64611c9e.006ed455.js create mode 100644 assets/js/64611c9e.fa02ea1c.js delete mode 100644 assets/js/65092830.b8ecad87.js rename assets/js/{34cb51de.65478ef8.js => 65092830.f2c41dec.js} (81%) delete mode 100644 assets/js/652bfc64.2188c1b2.js create mode 100644 assets/js/652bfc64.229d7087.js create mode 100644 assets/js/656a92e7.e21e3307.js delete mode 100644 assets/js/657d8ebd.0f987ef2.js create mode 100644 assets/js/657d8ebd.c5028931.js delete mode 100644 assets/js/65901721.47e584bf.js create mode 100644 assets/js/65901721.e21bc337.js create mode 100644 assets/js/65c0386d.13a4d3b1.js delete mode 100644 assets/js/65c0386d.dbe84a9d.js delete mode 100644 assets/js/65c96e54.25d5b87f.js create mode 100644 assets/js/65c96e54.d35dd311.js delete mode 100644 assets/js/66a8c7f6.12b39e4b.js create mode 100644 assets/js/66a8c7f6.85902c67.js delete mode 100644 assets/js/66cba0bd.60d2da65.js create mode 100644 assets/js/66cba0bd.faa47e96.js create mode 100644 assets/js/66f3d752.33d82cfe.js create mode 100644 assets/js/66f70f8f.4dcf0982.js delete mode 100644 assets/js/66f70f8f.85a454bc.js delete mode 100644 assets/js/673116d2.669abe58.js create mode 100644 assets/js/673116d2.efd92223.js create mode 100644 assets/js/6742155e.ae4cdb1b.js delete mode 100644 assets/js/6742155e.f14690e8.js delete mode 100644 assets/js/67533fec.02f4ab6f.js create mode 100644 assets/js/67533fec.0a3747e2.js create mode 100644 assets/js/682b4d18.5f92bb5d.js delete mode 100644 assets/js/682b4d18.ff9f6fcd.js rename assets/js/{4ee76bca.9d9c855d.js => 68387aed.6c485782.js} (95%) delete mode 100644 assets/js/68387aed.9c37a528.js create mode 100644 assets/js/687745aa.e3a44f5e.js delete mode 100644 assets/js/687745aa.ee3b15f1.js create mode 100644 assets/js/689c4956.4032913c.js delete mode 100644 assets/js/689c4956.f2bffe74.js create mode 100644 assets/js/68ebab0c.26c51eb9.js delete mode 100644 assets/js/68ebab0c.505e71ff.js create mode 100644 assets/js/68fb1eeb.6f093b68.js delete mode 100644 assets/js/68fb1eeb.737dc961.js delete mode 100644 assets/js/6920b208.2ca39706.js create mode 100644 assets/js/6920b208.ccc76c5e.js create mode 100644 assets/js/6996b984.b4f73bc7.js delete mode 100644 assets/js/6996b984.becc3d7a.js delete mode 100644 assets/js/6a657091.6e7caf8d.js create mode 100644 assets/js/6a657091.913fe8e5.js create mode 100644 assets/js/6a7380a0.db9ff9dc.js delete mode 100644 assets/js/6a7380a0.f99d149b.js delete mode 100644 assets/js/6a9eab1e.228f065d.js create mode 100644 assets/js/6a9eab1e.ab3db223.js delete mode 100644 assets/js/6b15d84e.71996085.js create mode 100644 assets/js/6b15d84e.febcf29d.js create mode 100644 assets/js/6bcde730.41fdc0f4.js delete mode 100644 assets/js/6bcde730.eb670e8a.js create mode 100644 assets/js/6c2831f5.4e93601b.js delete mode 100644 assets/js/6c2831f5.aeb89dd2.js delete mode 100644 assets/js/6cbc9f75.289091a9.js create mode 100644 assets/js/6cbc9f75.67d4a2a1.js delete mode 100644 assets/js/6d5f83d2.7366a0a9.js create mode 100644 assets/js/6d5f83d2.aa331710.js delete mode 100644 assets/js/6d989d91.1a76ebf5.js create mode 100644 assets/js/6d989d91.b21d4122.js create mode 100644 assets/js/6db5822b.41ba9d22.js delete mode 100644 assets/js/6db5822b.86299f29.js delete mode 100644 assets/js/6e20e454.782e3b18.js create mode 100644 assets/js/6e20e454.dd6fb97b.js delete mode 100644 assets/js/6e60fc8b.3ac840de.js create mode 100644 assets/js/6e60fc8b.aca356a4.js create mode 100644 assets/js/6e84f360.67048bd3.js delete mode 100644 assets/js/6e84f360.bd55039b.js create mode 100644 assets/js/6f1c5025.392919f0.js delete mode 100644 assets/js/6f1c5025.657daeda.js delete mode 100644 assets/js/6f91cedb.1268824b.js create mode 100644 assets/js/6f91cedb.dae20d28.js create mode 100644 assets/js/700a6203.96e5b25a.js delete mode 100644 assets/js/700a6203.e6792e5f.js create mode 100644 assets/js/702c04ed.4a8f4c3a.js delete mode 100644 assets/js/702c04ed.f33c7e72.js delete mode 100644 assets/js/706586ad.13f6fcf8.js create mode 100644 assets/js/706586ad.d57f0c83.js delete mode 100644 assets/js/7173f453.0649e776.js create mode 100644 assets/js/7173f453.9127f4e0.js delete mode 100644 assets/js/71f0a91e.b8762e40.js create mode 100644 assets/js/71f0a91e.c2b43331.js delete mode 100644 assets/js/72623072.5efc9424.js rename assets/js/{727dcb34.3bb0a6db.js => 72623072.7338e10b.js} (66%) create mode 100644 assets/js/726258db.05a4fdc5.js delete mode 100644 assets/js/726258db.be87e2de.js create mode 100644 assets/js/727dcb34.5a1cbb5e.js create mode 100644 assets/js/728e4eed.0709a7d1.js delete mode 100644 assets/js/728e4eed.d208fba0.js delete mode 100644 assets/js/7331483d.028c6ffa.js create mode 100644 assets/js/7331483d.53a5e6d9.js create mode 100644 assets/js/7349646d.56979680.js delete mode 100644 assets/js/7349646d.f03fb996.js delete mode 100644 assets/js/73e069de.db6dff06.js create mode 100644 assets/js/73e069de.df6d46b3.js delete mode 100644 assets/js/740a4079.a9309d7a.js create mode 100644 assets/js/740a4079.c9341847.js create mode 100644 assets/js/747296f3.b4b16fbf.js delete mode 100644 assets/js/747296f3.f8fc9c88.js create mode 100644 assets/js/74cc64ea.7b804d3a.js delete mode 100644 assets/js/74cc64ea.fb92a9b6.js create mode 100644 assets/js/74dddc49.9d85aa84.js create mode 100644 assets/js/7666c3a3.b0635687.js delete mode 100644 assets/js/7666c3a3.ef3ecff1.js create mode 100644 assets/js/768b23eb.5a9f0e97.js delete mode 100644 assets/js/768b23eb.e091e96e.js create mode 100644 assets/js/76c7e13e.cca1f363.js delete mode 100644 assets/js/76c7e13e.e4799098.js delete mode 100644 assets/js/774da543.b44038d8.js create mode 100644 assets/js/774da543.b4549ecc.js delete mode 100644 assets/js/775f7402.56e7aa31.js create mode 100644 assets/js/775f7402.a8a3553d.js delete mode 100644 assets/js/7766e9a3.bb4686eb.js create mode 100644 assets/js/7766e9a3.f7467a5f.js delete mode 100644 assets/js/77bc4eed.16348cfe.js create mode 100644 assets/js/77bc4eed.ae89a841.js delete mode 100644 assets/js/782adcf0.209702cb.js create mode 100644 assets/js/782adcf0.e9d6f902.js create mode 100644 assets/js/783ac7c2.24f9c08a.js delete mode 100644 assets/js/783ac7c2.c10d29c5.js create mode 100644 assets/js/78ba9b90.4e1bd74b.js delete mode 100644 assets/js/78ba9b90.fbe39829.js delete mode 100644 assets/js/78bf798d.07e36339.js create mode 100644 assets/js/78bf798d.57aa4d10.js delete mode 100644 assets/js/794916e1.387f08b1.js create mode 100644 assets/js/794916e1.491ace61.js delete mode 100644 assets/js/795486c3.042a464f.js create mode 100644 assets/js/795486c3.571c29ca.js create mode 100644 assets/js/7968a6dd.aaeb7699.js delete mode 100644 assets/js/7968a6dd.fb698d2d.js create mode 100644 assets/js/79c0e773.e680352b.js delete mode 100644 assets/js/7a6da112.57a10992.js create mode 100644 assets/js/7a6da112.efceb975.js create mode 100644 assets/js/7a9ccdde.742fd52e.js delete mode 100644 assets/js/7a9ccdde.9340217b.js delete mode 100644 assets/js/7a9ef260.849eae86.js rename assets/js/{0ae680de.c99e2d2c.js => 7a9ef260.b1c7cad6.js} (85%) create mode 100644 assets/js/7abea912.45ef7cb4.js delete mode 100644 assets/js/7abea912.a3b9d891.js create mode 100644 assets/js/7acfad2d.0d009458.js delete mode 100644 assets/js/7acfad2d.4e71b179.js create mode 100644 assets/js/7b4c5d89.981aa6c4.js delete mode 100644 assets/js/7b4c5d89.d9d3ced3.js delete mode 100644 assets/js/7b7ce1bb.b1f36699.js create mode 100644 assets/js/7b7ce1bb.fb591d47.js delete mode 100644 assets/js/7c3088cd.88920ebf.js create mode 100644 assets/js/7c3088cd.b77025a2.js delete mode 100644 assets/js/7c81245b.3f7ff4d2.js create mode 100644 assets/js/7c81245b.d396282e.js delete mode 100644 assets/js/7ca28631.c626d6c2.js create mode 100644 assets/js/7ca28631.cf3fe47d.js create mode 100644 assets/js/7ce1d7ba.4c892343.js delete mode 100644 assets/js/7ce1d7ba.eee60331.js create mode 100644 assets/js/7d540a1c.2c0773f4.js delete mode 100644 assets/js/7d540a1c.f06351bb.js delete mode 100644 assets/js/7de80a04.2ac7aa53.js create mode 100644 assets/js/7de80a04.baea3f7c.js delete mode 100644 assets/js/7e1818ad.bde2e8d8.js create mode 100644 assets/js/7e1818ad.c358bcce.js delete mode 100644 assets/js/7e9d6c07.713ea52f.js create mode 100644 assets/js/7e9d6c07.8f123222.js create mode 100644 assets/js/7ea4dca7.050efccb.js delete mode 100644 assets/js/7ea4dca7.1bea8506.js delete mode 100644 assets/js/7f4ab349.9d4b95b6.js create mode 100644 assets/js/7f4ab349.f5cbe695.js delete mode 100644 assets/js/7f4c5c7b.221ae515.js create mode 100644 assets/js/7f4c5c7b.9b49b785.js delete mode 100644 assets/js/7f9ffb40.143a22ba.js create mode 100644 assets/js/7f9ffb40.425fe902.js create mode 100644 assets/js/7fa6c7d7.621aef7a.js delete mode 100644 assets/js/7fa6c7d7.abbaa74a.js create mode 100644 assets/js/7fdd84c3.7851bc0c.js delete mode 100644 assets/js/7fdd84c3.b7b7143f.js rename assets/js/{fb61b539.ef5d6189.js => 7ff8ae66.91a83928.js} (93%) delete mode 100644 assets/js/7ff8ae66.adc82365.js delete mode 100644 assets/js/8038297c.4b1d6c16.js create mode 100644 assets/js/8038297c.55055184.js create mode 100644 assets/js/807a296b.3d83cb0d.js delete mode 100644 assets/js/807a296b.f0db713e.js create mode 100644 assets/js/81c00f7a.a8bd4bcc.js delete mode 100644 assets/js/81c00f7a.d07c0a8e.js rename assets/js/{5ab2e4c0.782e7a72.js => 822c4cd0.1e8acb80.js} (85%) delete mode 100644 assets/js/822c4cd0.550004ca.js rename assets/js/{11415922.86d9309c.js => 8235289d.4871563d.js} (85%) delete mode 100644 assets/js/8235289d.b5061697.js create mode 100644 assets/js/82e28990.92e307dc.js delete mode 100644 assets/js/82e28990.cfaf30af.js create mode 100644 assets/js/837a6211.05aa0106.js delete mode 100644 assets/js/837a6211.2ffc4089.js create mode 100644 assets/js/83caed44.43ec86bc.js delete mode 100644 assets/js/83caed44.6b08ae13.js create mode 100644 assets/js/83fbfe62.b0f06499.js delete mode 100644 assets/js/83fbfe62.d227a287.js delete mode 100644 assets/js/84328430.4ca5699f.js create mode 100644 assets/js/84328430.f5149255.js delete mode 100644 assets/js/845d6e8e.1909746f.js create mode 100644 assets/js/845d6e8e.487273e9.js delete mode 100644 assets/js/84eeefe6.37c5ccb6.js create mode 100644 assets/js/84eeefe6.dae70540.js rename assets/js/{fd0ee3c6.61056912.js => 84faaee0.2d344468.js} (57%) delete mode 100644 assets/js/84faaee0.6eb99f25.js delete mode 100644 assets/js/8526f5f6.a458fa75.js create mode 100644 assets/js/8526f5f6.e9068c90.js create mode 100644 assets/js/85618d7a.50311b87.js delete mode 100644 assets/js/85618d7a.5a8afe71.js delete mode 100644 assets/js/85811646.0fb00ca3.js create mode 100644 assets/js/85811646.91532574.js create mode 100644 assets/js/86802c4c.8ea7b443.js delete mode 100644 assets/js/86802c4c.e57750ec.js create mode 100644 assets/js/868dd308.14f7b41c.js delete mode 100644 assets/js/868dd308.e92ff638.js delete mode 100644 assets/js/87542a62.1b49b92a.js create mode 100644 assets/js/87542a62.cad825b0.js create mode 100644 assets/js/8853f2c2.220d2c15.js delete mode 100644 assets/js/8853f2c2.5ee3e40d.js rename assets/js/{1d2426fc.723beb65.js => 885a7d6a.42a1b0d6.js} (51%) delete mode 100644 assets/js/885a7d6a.e4dcab5c.js delete mode 100644 assets/js/8865241c.149ab5cd.js create mode 100644 assets/js/8865241c.eb758e6c.js delete mode 100644 assets/js/8866cdc6.78170166.js create mode 100644 assets/js/8866cdc6.f2a0408b.js create mode 100644 assets/js/88b3827b.026a2161.js delete mode 100644 assets/js/88b3827b.7f50d46d.js create mode 100644 assets/js/88fe791b.1bc618ab.js delete mode 100644 assets/js/88fe791b.4b1aa31a.js delete mode 100644 assets/js/895dee77.e3366a0f.js create mode 100644 assets/js/895dee77.fb50ae5c.js create mode 100644 assets/js/899fb7ad.0855184c.js delete mode 100644 assets/js/899fb7ad.4f693ba9.js create mode 100644 assets/js/89ca3add.3b674072.js delete mode 100644 assets/js/89ca3add.3eb9ec9a.js create mode 100644 assets/js/8b7b5312.b2d3196f.js delete mode 100644 assets/js/8b7b5312.f5664dc9.js create mode 100644 assets/js/8c6e7842.b3f5d0a0.js delete mode 100644 assets/js/8c6e7842.d70de832.js delete mode 100644 assets/js/8d08212b.4cd5d329.js rename assets/js/{a7750664.8bc6753d.js => 8d08212b.f53c6cb2.js} (66%) delete mode 100644 assets/js/8d2c35d4.1fd44b34.js create mode 100644 assets/js/8d2c35d4.c633d23f.js create mode 100644 assets/js/8dc9f855.bbdaaf47.js delete mode 100644 assets/js/8dc9f855.ea1fdf8f.js create mode 100644 assets/js/8e81a754.081f2590.js delete mode 100644 assets/js/8e81a754.1f78dc3b.js create mode 100644 assets/js/8eb806f1.616ce5b5.js delete mode 100644 assets/js/8eb806f1.74a75e1b.js delete mode 100644 assets/js/8eeb7ef3.334acc23.js create mode 100644 assets/js/8eeb7ef3.a30db3ae.js delete mode 100644 assets/js/8ef337ca.17610190.js create mode 100644 assets/js/8ef337ca.38d95d08.js create mode 100644 assets/js/8f60a0b3.33e3c536.js delete mode 100644 assets/js/8f60a0b3.80d0d86d.js delete mode 100644 assets/js/90a92006.11cbc061.js create mode 100644 assets/js/90a92006.f478e11f.js create mode 100644 assets/js/90dad6ee.2ba4bd93.js delete mode 100644 assets/js/90dad6ee.77b931b5.js create mode 100644 assets/js/913f9301.afae53b5.js delete mode 100644 assets/js/913f9301.dc12e4b5.js delete mode 100644 assets/js/9142ac60.ace42db5.js create mode 100644 assets/js/9142ac60.d2a33e18.js delete mode 100644 assets/js/91a30c6c.1b81304d.js create mode 100644 assets/js/91a30c6c.6223bea4.js create mode 100644 assets/js/91b81b98.36f13bee.js delete mode 100644 assets/js/91b81b98.6e89d14e.js create mode 100644 assets/js/91cbd683.09f02c8a.js delete mode 100644 assets/js/91cbd683.58dfcf19.js delete mode 100644 assets/js/92574a95.a12cf8a7.js create mode 100644 assets/js/92574a95.bff193a9.js create mode 100644 assets/js/9262865a.392a33e6.js delete mode 100644 assets/js/9262865a.bb6a2388.js delete mode 100644 assets/js/931d717b.3a717e33.js create mode 100644 assets/js/931d717b.a83c1f7e.js create mode 100644 assets/js/932325e3.12326c77.js delete mode 100644 assets/js/932325e3.8f3453ca.js create mode 100644 assets/js/93a69b01.bca7472f.js delete mode 100644 assets/js/93a69b01.c7b22ad1.js delete mode 100644 assets/js/93ce49f2.b92c22b6.js create mode 100644 assets/js/93ce49f2.ec513a16.js create mode 100644 assets/js/942689f6.3e875707.js delete mode 100644 assets/js/942689f6.a83d794e.js create mode 100644 assets/js/943dca3e.33d026b4.js delete mode 100644 assets/js/943dca3e.b89cfdee.js create mode 100644 assets/js/949da420.92c6afcd.js delete mode 100644 assets/js/949da420.ca243db4.js create mode 100644 assets/js/94b95b8f.31bc4e87.js delete mode 100644 assets/js/94b95b8f.6fe5a0b2.js create mode 100644 assets/js/94baf93c.1346c995.js delete mode 100644 assets/js/94baf93c.e5255d89.js delete mode 100644 assets/js/95033604.6c54c0f9.js create mode 100644 assets/js/95033604.6e0b92c9.js create mode 100644 assets/js/9522257f.63de51ed.js delete mode 100644 assets/js/9522257f.6dabdd55.js create mode 100644 assets/js/955c0e5b.6bc4f2fc.js delete mode 100644 assets/js/955c0e5b.96f77ef0.js delete mode 100644 assets/js/95914a86.693fa2c3.js create mode 100644 assets/js/95914a86.e731d00e.js create mode 100644 assets/js/95a8058e.980b2f0d.js delete mode 100644 assets/js/95a8058e.f549b041.js create mode 100644 assets/js/95c01cd8.51a21012.js delete mode 100644 assets/js/95c01cd8.fe03e801.js delete mode 100644 assets/js/961f481b.47c1dab2.js create mode 100644 assets/js/961f481b.8a8833a3.js delete mode 100644 assets/js/965f64c7.c99d33ba.js create mode 100644 assets/js/965f64c7.f5dcb8be.js create mode 100644 assets/js/969375ac.2039b518.js delete mode 100644 assets/js/969375ac.cc8f97ac.js delete mode 100644 assets/js/98482f87.3a14148e.js create mode 100644 assets/js/98482f87.ba66c749.js delete mode 100644 assets/js/986cf98d.9183506e.js create mode 100644 assets/js/986cf98d.eef99780.js create mode 100644 assets/js/98a5c5a6.722f5043.js delete mode 100644 assets/js/98a5c5a6.8b4da06f.js create mode 100644 assets/js/991975ae.6f92fe43.js delete mode 100644 assets/js/991975ae.ea6af4ba.js delete mode 100644 assets/js/9961d4c6.4b28e906.js create mode 100644 assets/js/9961d4c6.c2163285.js create mode 100644 assets/js/99a448bd.d64e6414.js delete mode 100644 assets/js/9afd861b.1e6d0ff8.js create mode 100644 assets/js/9afd861b.53375667.js create mode 100644 assets/js/9b395cf6.8b391952.js delete mode 100644 assets/js/9b395cf6.e59243e4.js delete mode 100644 assets/js/9b8cf09a.260b9fd5.js create mode 100644 assets/js/9b8cf09a.7ce01f1e.js create mode 100644 assets/js/9b8fa1b3.90180355.js delete mode 100644 assets/js/9b8fa1b3.d10d4d75.js delete mode 100644 assets/js/9ba4de84.a8e5689e.js create mode 100644 assets/js/9ba4de84.ef5d2119.js create mode 100644 assets/js/9bae3a4c.a4c72abc.js delete mode 100644 assets/js/9bae3a4c.ddcdb0d5.js delete mode 100644 assets/js/9c78aef9.1e9582a9.js create mode 100644 assets/js/9c78aef9.c393acac.js create mode 100644 assets/js/9c83163a.19279b88.js delete mode 100644 assets/js/9c83163a.35fe8eb9.js create mode 100644 assets/js/9cc4f97f.47dc6e88.js delete mode 100644 assets/js/9cc4f97f.83b18ef3.js create mode 100644 assets/js/9dd53394.65ea421d.js delete mode 100644 assets/js/9dd53394.c731354a.js delete mode 100644 assets/js/9e00d6e3.4d5d951e.js create mode 100644 assets/js/9e00d6e3.c2934eac.js create mode 100644 assets/js/9ecee934.3a26908e.js delete mode 100644 assets/js/9ecee934.fe9e2e8b.js delete mode 100644 assets/js/9f3200bd.1360fd7c.js rename assets/js/{3c7d7aed.326021a0.js => 9f3200bd.7c76d583.js} (88%) create mode 100644 assets/js/9f710d35.61b64e3a.js delete mode 100644 assets/js/9f710d35.8ac716b4.js create mode 100644 assets/js/9f8e45fd.00eb5db2.js delete mode 100644 assets/js/9f8e45fd.ec4b51c9.js delete mode 100644 assets/js/a04054f5.00728a15.js create mode 100644 assets/js/a04054f5.cba09eff.js create mode 100644 assets/js/a152e2a1.7b870a4d.js delete mode 100644 assets/js/a152e2a1.f674210f.js create mode 100644 assets/js/a1972f12.4378dbcb.js delete mode 100644 assets/js/a1972f12.79c7be37.js create mode 100644 assets/js/a1f54622.1e7dfb27.js delete mode 100644 assets/js/a1f54622.dad77d20.js create mode 100644 assets/js/a2228310.144c4435.js delete mode 100644 assets/js/a2228310.5227e7b0.js delete mode 100644 assets/js/a222ac46.a29026af.js create mode 100644 assets/js/a222ac46.fe12bdf1.js delete mode 100644 assets/js/a227e3bb.81c53baf.js create mode 100644 assets/js/a227e3bb.f7a5a0af.js delete mode 100644 assets/js/a2379942.2970f651.js create mode 100644 assets/js/a2379942.568c7441.js create mode 100644 assets/js/a29568cd.263cc2c5.js delete mode 100644 assets/js/a29568cd.fd893b77.js create mode 100644 assets/js/a2b3d820.42df04fe.js delete mode 100644 assets/js/a2b3d820.a10cf547.js create mode 100644 assets/js/a2f052bb.6c125bef.js delete mode 100644 assets/js/a2f052bb.a60b4a1d.js delete mode 100644 assets/js/a3433b4a.1b9d5040.js create mode 100644 assets/js/a3433b4a.20c6ce95.js delete mode 100644 assets/js/a3bdbb47.5c9d534a.js create mode 100644 assets/js/a3bdbb47.e100534f.js delete mode 100644 assets/js/a4064c4a.a7117d3c.js create mode 100644 assets/js/a4064c4a.d44c39d0.js delete mode 100644 assets/js/a43a10ce.8b121097.js create mode 100644 assets/js/a43a10ce.f8a1abc6.js create mode 100644 assets/js/a4731843.4aa10422.js delete mode 100644 assets/js/a4731843.e8877402.js create mode 100644 assets/js/a56250de.32b055f3.js delete mode 100644 assets/js/a56250de.5e0313e4.js create mode 100644 assets/js/a56a649d.972d90d6.js delete mode 100644 assets/js/a56a649d.9fb527f8.js create mode 100644 assets/js/a5c83061.06197815.js delete mode 100644 assets/js/a5c83061.34440fd9.js delete mode 100644 assets/js/a5c8e3ee.0e93dcd6.js create mode 100644 assets/js/a5c8e3ee.ca2bd0a2.js delete mode 100644 assets/js/a6347505.d2623b16.js create mode 100644 assets/js/a6347505.fa46a092.js delete mode 100644 assets/js/a65aeb22.05854d06.js create mode 100644 assets/js/a65aeb22.882327db.js delete mode 100644 assets/js/a6838072.4e97ee06.js create mode 100644 assets/js/a6838072.d5105d67.js create mode 100644 assets/js/a6a59c72.73c7cc8c.js delete mode 100644 assets/js/a6a59c72.80aad573.js delete mode 100644 assets/js/a6e67d36.1bcff134.js create mode 100644 assets/js/a6e67d36.293286ae.js create mode 100644 assets/js/a6f546c7.80e90cf4.js delete mode 100644 assets/js/a6f546c7.94c52fef.js create mode 100644 assets/js/a7059e68.a3f1b60d.js delete mode 100644 assets/js/a7059e68.eb1a7d00.js delete mode 100644 assets/js/a7434e38.103a0bf2.js create mode 100644 assets/js/a7434e38.e7e01e27.js create mode 100644 assets/js/a7750664.61def123.js create mode 100644 assets/js/a85d3042.00032cd4.js delete mode 100644 assets/js/a85d3042.e0bf13c4.js create mode 100644 assets/js/a8a78a40.a64b4581.js delete mode 100644 assets/js/a8a78a40.d328644f.js create mode 100644 assets/js/a92c605c.1e410043.js delete mode 100644 assets/js/a92c605c.2bcb927d.js create mode 100644 assets/js/a94703ab.74081b1d.js delete mode 100644 assets/js/a94703ab.ed43bbde.js delete mode 100644 assets/js/a99a7a84.43c2e13b.js create mode 100644 assets/js/a99a7a84.4a569cbd.js delete mode 100644 assets/js/ab039f39.49d2752e.js rename assets/js/{66f3d752.7f8fdf7c.js => ab039f39.f8adde32.js} (90%) delete mode 100644 assets/js/abad1954.28a5cdfe.js create mode 100644 assets/js/abad1954.d1a61ab3.js create mode 100644 assets/js/abb8b5df.024ffd0b.js delete mode 100644 assets/js/abb8b5df.122e1a24.js delete mode 100644 assets/js/ac036e1a.5de1ac68.js create mode 100644 assets/js/ac036e1a.fac6ddbd.js create mode 100644 assets/js/ac18aa78.299f608f.js delete mode 100644 assets/js/ac18aa78.bce15754.js create mode 100644 assets/js/ac305c95.27a1f7bb.js delete mode 100644 assets/js/ac305c95.9523608a.js delete mode 100644 assets/js/ac8215b1.6e7b6842.js create mode 100644 assets/js/ac8215b1.d1a41fbf.js create mode 100644 assets/js/aca294da.0357d2e2.js delete mode 100644 assets/js/aca294da.218f25e0.js create mode 100644 assets/js/add034c7.86644d5e.js delete mode 100644 assets/js/add034c7.afcb4611.js create mode 100644 assets/js/ae1a4dc5.3ccf2757.js delete mode 100644 assets/js/ae1a4dc5.8debe308.js delete mode 100644 assets/js/ae2933e0.7e46d046.js create mode 100644 assets/js/ae2933e0.bf9af1da.js delete mode 100644 assets/js/ae61132c.054cbffa.js create mode 100644 assets/js/ae61132c.e80189e1.js create mode 100644 assets/js/ae7ab5ca.bb5fface.js delete mode 100644 assets/js/ae7ab5ca.e1769ae9.js create mode 100644 assets/js/af09c9fa.4af5355c.js delete mode 100644 assets/js/af09c9fa.ed66a051.js delete mode 100644 assets/js/af189017.9fa1c39e.js create mode 100644 assets/js/af189017.ef0201fa.js create mode 100644 assets/js/afa9352b.07965f20.js delete mode 100644 assets/js/afa9352b.6100ef08.js delete mode 100644 assets/js/afc94b42.ac49af9d.js create mode 100644 assets/js/afc94b42.ef6dd603.js delete mode 100644 assets/js/afe3f069.635e5561.js create mode 100644 assets/js/afe3f069.86a1a830.js delete mode 100644 assets/js/afe76ad3.03926a60.js create mode 100644 assets/js/afe76ad3.2b19a28e.js delete mode 100644 assets/js/b064ae39.6d4d3e73.js create mode 100644 assets/js/b064ae39.e90a9ae9.js delete mode 100644 assets/js/b15cf43f.a350eca9.js create mode 100644 assets/js/b15cf43f.e2ee5769.js delete mode 100644 assets/js/b1b1702b.1e5c93c4.js create mode 100644 assets/js/b1b1702b.d2345b03.js create mode 100644 assets/js/b1d4c921.6c5336f5.js delete mode 100644 assets/js/b1d4c921.78452bfa.js create mode 100644 assets/js/b2214eb1.3ef66475.js delete mode 100644 assets/js/b2214eb1.e13b9368.js create mode 100644 assets/js/b258137a.5657a8cc.js delete mode 100644 assets/js/b258137a.d95a8760.js delete mode 100644 assets/js/b27813ce.1bb9f03f.js create mode 100644 assets/js/b27813ce.5809c4ed.js rename assets/js/{79c0e773.a2544b1f.js => b2c09c04.1c8505b5.js} (89%) delete mode 100644 assets/js/b2c09c04.8a5b31d8.js create mode 100644 assets/js/b354a552.8ba8b65a.js delete mode 100644 assets/js/b354a552.bb2070c0.js create mode 100644 assets/js/b3d255a8.4f717977.js delete mode 100644 assets/js/b3d255a8.eafe1a61.js delete mode 100644 assets/js/b487db90.d8dfc936.js create mode 100644 assets/js/b487db90.ec20f180.js delete mode 100644 assets/js/b4b1dbe6.9d752ca4.js create mode 100644 assets/js/b4b1dbe6.a69557ad.js create mode 100644 assets/js/b4d23454.29d9e249.js delete mode 100644 assets/js/b4d23454.79db2291.js delete mode 100644 assets/js/b4f08813.1855444d.js create mode 100644 assets/js/b4f08813.984bb553.js delete mode 100644 assets/js/b5493e20.0c765ef3.js create mode 100644 assets/js/b5493e20.ce949b2a.js delete mode 100644 assets/js/b5b69494.96d93d10.js create mode 100644 assets/js/b5b69494.bebc807b.js delete mode 100644 assets/js/b68a0da6.41a0aa15.js create mode 100644 assets/js/b68a0da6.7c19837a.js delete mode 100644 assets/js/b695d366.4c8cc28c.js create mode 100644 assets/js/b695d366.7bc5d5fc.js create mode 100644 assets/js/b6bd0417.8092c106.js delete mode 100644 assets/js/b6bd0417.f2d34759.js delete mode 100644 assets/js/b85d43e2.5b8d814a.js create mode 100644 assets/js/b85d43e2.b6bdf0cf.js delete mode 100644 assets/js/b8e59b2c.0a9f7c0e.js create mode 100644 assets/js/b8e59b2c.0b7afc2a.js create mode 100644 assets/js/b92b9889.c72ee478.js delete mode 100644 assets/js/b92b9889.e3be9837.js delete mode 100644 assets/js/b939d93e.656c71c1.js create mode 100644 assets/js/b939d93e.d0b11db7.js delete mode 100644 assets/js/b9b95a14.1514e617.js create mode 100644 assets/js/b9b95a14.ab4399a9.js create mode 100644 assets/js/ba8f881f.4a933e9a.js delete mode 100644 assets/js/ba8f881f.b798691c.js create mode 100644 assets/js/ba942c4a.926de97a.js delete mode 100644 assets/js/ba942c4a.b9efcac7.js create mode 100644 assets/js/bb3b54eb.621ca474.js delete mode 100644 assets/js/bb3b54eb.fb334890.js delete mode 100644 assets/js/bb7ff5c7.0831e5cd.js create mode 100644 assets/js/bb7ff5c7.7b7d83e4.js delete mode 100644 assets/js/bbe812b2.226d9347.js create mode 100644 assets/js/bbe812b2.f93181ac.js delete mode 100644 assets/js/bc0e42ae.4a3c9cef.js create mode 100644 assets/js/bc0e42ae.f3014624.js delete mode 100644 assets/js/bc158748.81faac3c.js create mode 100644 assets/js/bc158748.8edd1e0a.js delete mode 100644 assets/js/bc580689.168fe4ba.js create mode 100644 assets/js/bc580689.aaa89f18.js delete mode 100644 assets/js/bc72aaf9.07b6e644.js create mode 100644 assets/js/bc72aaf9.9c555370.js delete mode 100644 assets/js/bcaec485.924c50cd.js create mode 100644 assets/js/bcaec485.c0f82cc2.js delete mode 100644 assets/js/bced3f71.4aff0b2b.js create mode 100644 assets/js/bced3f71.c6848614.js create mode 100644 assets/js/bd9dcf8a.bcaf680c.js delete mode 100644 assets/js/bd9dcf8a.c543192c.js create mode 100644 assets/js/be191a2f.2e971851.js delete mode 100644 assets/js/be191a2f.d666565b.js delete mode 100644 assets/js/be47e46c.23a795fc.js create mode 100644 assets/js/be47e46c.a09eeb56.js delete mode 100644 assets/js/bfa69319.a5ece7bf.js create mode 100644 assets/js/bfa69319.c71d9255.js delete mode 100644 assets/js/bfb8c06b.04aafba0.js create mode 100644 assets/js/bfb8c06b.34868e2b.js create mode 100644 assets/js/c05e6243.632a34b2.js delete mode 100644 assets/js/c05e6243.b883b197.js create mode 100644 assets/js/c1a2c389.870fa00f.js delete mode 100644 assets/js/c1a2c389.cc12095d.js delete mode 100644 assets/js/c34fec7a.4c361055.js create mode 100644 assets/js/c34fec7a.8c409f6f.js create mode 100644 assets/js/c3b7d73e.60b98df8.js delete mode 100644 assets/js/c3b7d73e.6a078ddd.js create mode 100644 assets/js/c3c1383c.9de4b2c7.js delete mode 100644 assets/js/c3c1383c.fb4b970f.js delete mode 100644 assets/js/c3c2cf0d.64ac343b.js create mode 100644 assets/js/c3c2cf0d.8af95259.js delete mode 100644 assets/js/c3f10aa7.e949e8cb.js create mode 100644 assets/js/c3f10aa7.f665adb9.js delete mode 100644 assets/js/c4dc49db.592414c9.js create mode 100644 assets/js/c4dc49db.f8f6b241.js delete mode 100644 assets/js/c4f63a35.18366e52.js create mode 100644 assets/js/c4f63a35.ce34965f.js delete mode 100644 assets/js/c51a5554.95cc16da.js create mode 100644 assets/js/c51a5554.ded96e4c.js delete mode 100644 assets/js/c54faebb.0a09e519.js rename assets/js/{656a92e7.e8008734.js => c54faebb.d24bb846.js} (89%) delete mode 100644 assets/js/c55714c1.10a185e6.js create mode 100644 assets/js/c55714c1.4a3febaf.js create mode 100644 assets/js/c5e2ef47.10ddc021.js delete mode 100644 assets/js/c5e2ef47.2767559f.js delete mode 100644 assets/js/c6148b7b.7adc2b38.js create mode 100644 assets/js/c6148b7b.aedc22ee.js delete mode 100644 assets/js/c679c49e.66e36f68.js create mode 100644 assets/js/c679c49e.83ffb8e6.js create mode 100644 assets/js/c68e47be.8230e904.js delete mode 100644 assets/js/c68e47be.e81d9b32.js create mode 100644 assets/js/c6cb80e5.0f108168.js delete mode 100644 assets/js/c6cb80e5.a3e29e81.js delete mode 100644 assets/js/c75b9003.96f8a684.js create mode 100644 assets/js/c75b9003.e70c4ed2.js delete mode 100644 assets/js/c7901ae7.975ad6b7.js create mode 100644 assets/js/c7901ae7.ef94f99b.js delete mode 100644 assets/js/c80a87e5.20767268.js create mode 100644 assets/js/c80a87e5.2838282c.js create mode 100644 assets/js/c8415933.ac018e8c.js delete mode 100644 assets/js/c8415933.c84ea069.js delete mode 100644 assets/js/c85edbf4.2a0ba7e3.js create mode 100644 assets/js/c85edbf4.5014f68d.js delete mode 100644 assets/js/c866602a.4378ae95.js create mode 100644 assets/js/c866602a.94cdfbfa.js delete mode 100644 assets/js/c8b23694.b29c7f4c.js create mode 100644 assets/js/c8b23694.bb4dde32.js delete mode 100644 assets/js/c8c040fd.ae4b02f1.js create mode 100644 assets/js/c8c040fd.fabc04ce.js delete mode 100644 assets/js/c8d42f80.39faa782.js create mode 100644 assets/js/c8d42f80.d25e28c6.js create mode 100644 assets/js/c9264c9d.8225593c.js delete mode 100644 assets/js/c9264c9d.8a29cd5c.js create mode 100644 assets/js/c926f228.041f2481.js delete mode 100644 assets/js/c926f228.055a5786.js create mode 100644 assets/js/c9802e0f.76775190.js delete mode 100644 assets/js/c9802e0f.cad55d94.js delete mode 100644 assets/js/c9d8ba84.9889eb8a.js create mode 100644 assets/js/c9d8ba84.e7ce850c.js delete mode 100644 assets/js/c9df2073.00f820bc.js rename assets/js/{3a6bbf33.0db4ae19.js => c9df2073.5d30817f.js} (90%) delete mode 100644 assets/js/ca516ab1.4c67cb96.js create mode 100644 assets/js/ca516ab1.a631cfb5.js create mode 100644 assets/js/ca823d8e.130e2e10.js delete mode 100644 assets/js/ca823d8e.51afea5d.js create mode 100644 assets/js/ca88f7f6.7f644b3a.js delete mode 100644 assets/js/ca88f7f6.acfc823d.js delete mode 100644 assets/js/ca9696ff.94c2e157.js create mode 100644 assets/js/ca9696ff.accfe967.js create mode 100644 assets/js/ca9a1315.412149f7.js delete mode 100644 assets/js/ca9a1315.dc0361ec.js delete mode 100644 assets/js/cb1127ff.04b6a692.js create mode 100644 assets/js/cb1127ff.29f051a6.js create mode 100644 assets/js/cb6ed70c.1c8887b4.js delete mode 100644 assets/js/cb6ed70c.c07e2af3.js create mode 100644 assets/js/cb7ce1df.837d758a.js delete mode 100644 assets/js/cb7ce1df.f8cf63d3.js delete mode 100644 assets/js/cb8aebd7.1cc26a81.js create mode 100644 assets/js/cb8aebd7.58c83db3.js delete mode 100644 assets/js/cbefe8e6.20c007d1.js create mode 100644 assets/js/cbefe8e6.d024ab6e.js delete mode 100644 assets/js/cc417f5b.b65cd895.js create mode 100644 assets/js/cc417f5b.e224d1b6.js delete mode 100644 assets/js/cd1fd97e.37b9f5ef.js create mode 100644 assets/js/cd1fd97e.5bdccd93.js create mode 100644 assets/js/cdaeb6c7.6f357f99.js delete mode 100644 assets/js/cdaeb6c7.df2df551.js create mode 100644 assets/js/ce1e026e.1867bc79.js delete mode 100644 assets/js/ce1e026e.c5b4c67b.js delete mode 100644 assets/js/ce3faf2d.23d2d6e9.js create mode 100644 assets/js/ce3faf2d.6f1571d9.js create mode 100644 assets/js/cee57922.17adfa9b.js delete mode 100644 assets/js/cee57922.6d5b56df.js create mode 100644 assets/js/cf66eb9a.851599bd.js delete mode 100644 assets/js/cf66eb9a.a8e51d9f.js create mode 100644 assets/js/cf73d354.6e96f0a4.js delete mode 100644 assets/js/cf73d354.9b158036.js delete mode 100644 assets/js/cf870e39.50637f5a.js create mode 100644 assets/js/cf870e39.7a0bbf02.js delete mode 100644 assets/js/cfa831f6.9bd7c726.js create mode 100644 assets/js/cfa831f6.a3ef1de2.js create mode 100644 assets/js/cfa8b089.2654650c.js delete mode 100644 assets/js/cfa8b089.eef179db.js delete mode 100644 assets/js/cfb416dc.2ccf7923.js create mode 100644 assets/js/cfb416dc.2fb6a6d7.js create mode 100644 assets/js/cfda7dae.e4f6ed3f.js delete mode 100644 assets/js/cfda7dae.fe188d50.js create mode 100644 assets/js/cfe35add.c291102a.js delete mode 100644 assets/js/cfe35add.de35aac6.js delete mode 100644 assets/js/d01c17fe.53bfc8f4.js create mode 100644 assets/js/d01c17fe.a861bb4f.js create mode 100644 assets/js/d02faa29.1e681f42.js delete mode 100644 assets/js/d02faa29.e9248f9b.js create mode 100644 assets/js/d0711b6d.42c8f2df.js delete mode 100644 assets/js/d0711b6d.85b75c47.js create mode 100644 assets/js/d07c7386.09443deb.js delete mode 100644 assets/js/d07c7386.90fad743.js create mode 100644 assets/js/d0cd86ed.08a40290.js delete mode 100644 assets/js/d0cd86ed.531bf319.js create mode 100644 assets/js/d0dab5bd.98023ad6.js delete mode 100644 assets/js/d0dab5bd.f6748cbd.js create mode 100644 assets/js/d0e063b4.12510200.js delete mode 100644 assets/js/d0e063b4.fdb2e57a.js delete mode 100644 assets/js/d0e24277.58dd1984.js create mode 100644 assets/js/d0e24277.9ecd708b.js delete mode 100644 assets/js/d1642eb0.08cc111f.js create mode 100644 assets/js/d1642eb0.248990b5.js delete mode 100644 assets/js/d1da8056.76b7e6df.js create mode 100644 assets/js/d1da8056.bbfb4757.js delete mode 100644 assets/js/d1f820e6.2567ee43.js create mode 100644 assets/js/d1f820e6.98d6fd2f.js create mode 100644 assets/js/d22c73ca.305928ed.js delete mode 100644 assets/js/d22c73ca.dc6c6912.js delete mode 100644 assets/js/d249d4cd.22221e35.js create mode 100644 assets/js/d249d4cd.dcbafdfe.js create mode 100644 assets/js/d32dcc20.3ef11828.js delete mode 100644 assets/js/d32dcc20.3fbce5a2.js create mode 100644 assets/js/d3774da1.643e7434.js delete mode 100644 assets/js/d3774da1.d07771e1.js create mode 100644 assets/js/d388c1c0.21ad8b7f.js delete mode 100644 assets/js/d388c1c0.9d5a1ae0.js delete mode 100644 assets/js/d39b0ace.4b669191.js create mode 100644 assets/js/d39b0ace.6f712eb7.js create mode 100644 assets/js/d41b86be.2441c8e9.js delete mode 100644 assets/js/d41b86be.b2f8a13b.js create mode 100644 assets/js/d46d00ce.56054b22.js delete mode 100644 assets/js/d46d00ce.6a7808e4.js create mode 100644 assets/js/d50422d0.8ea73767.js delete mode 100644 assets/js/d50422d0.b9bfda39.js delete mode 100644 assets/js/d505d09c.97f4652b.js create mode 100644 assets/js/d505d09c.fb00c194.js delete mode 100644 assets/js/d565a856.28156f55.js create mode 100644 assets/js/d565a856.b60afede.js delete mode 100644 assets/js/d5863f70.20f48776.js create mode 100644 assets/js/d5863f70.6a0f8935.js delete mode 100644 assets/js/d58c4aef.0a940ec7.js create mode 100644 assets/js/d58c4aef.fb51545b.js create mode 100644 assets/js/d636f068.00b70d2f.js delete mode 100644 assets/js/d636f068.3ccdb8b4.js create mode 100644 assets/js/d6467a7b.a5739b7c.js delete mode 100644 assets/js/d6467a7b.e46b8a62.js delete mode 100644 assets/js/d65f0d11.759d5ac0.js create mode 100644 assets/js/d65f0d11.eb4111cf.js create mode 100644 assets/js/d68a8932.1b5a522f.js delete mode 100644 assets/js/d68a8932.e4d879a9.js delete mode 100644 assets/js/d6b2ce60.0b775b00.js create mode 100644 assets/js/d6b2ce60.db005195.js create mode 100644 assets/js/d7fccb5c.1b2ba836.js delete mode 100644 assets/js/d7fccb5c.dcac1a9d.js delete mode 100644 assets/js/d8e67ba0.57982001.js create mode 100644 assets/js/d8e67ba0.bf7c219e.js delete mode 100644 assets/js/d9120bf2.d4f61e45.js create mode 100644 assets/js/d9120bf2.fc753897.js create mode 100644 assets/js/d9135261.1a5f5d2d.js delete mode 100644 assets/js/d9135261.78759909.js rename assets/js/{99a448bd.7ba4068b.js => d984a461.59ec4632.js} (65%) delete mode 100644 assets/js/d984a461.6f260e9f.js delete mode 100644 assets/js/d9b89ec4.27e16f78.js create mode 100644 assets/js/d9b89ec4.3b19144b.js create mode 100644 assets/js/d9fbf9ee.5b173e0e.js delete mode 100644 assets/js/d9fbf9ee.9b0b3890.js create mode 100644 assets/js/da50bba4.16de0ccc.js delete mode 100644 assets/js/da50bba4.b307065b.js create mode 100644 assets/js/da6b5a00.ca5f497f.js delete mode 100644 assets/js/da6b5a00.dc7521bb.js create mode 100644 assets/js/da8b62d5.1f0a74bc.js delete mode 100644 assets/js/da8b62d5.e0e4cfeb.js delete mode 100644 assets/js/dabc210e.b09a6698.js create mode 100644 assets/js/dabc210e.bafeb6df.js create mode 100644 assets/js/dad18bc2.5b4819f1.js delete mode 100644 assets/js/dad18bc2.a8cd7721.js delete mode 100644 assets/js/dbbd275b.0265e406.js create mode 100644 assets/js/dbbd275b.411a5113.js delete mode 100644 assets/js/dc0b502e.9cc56b8b.js create mode 100644 assets/js/dc0b502e.c9fcee55.js delete mode 100644 assets/js/dccfc6ca.cb51e9b5.js create mode 100644 assets/js/dccfc6ca.e572b874.js create mode 100644 assets/js/dd0d07c1.18865095.js delete mode 100644 assets/js/dd0d07c1.689e9934.js create mode 100644 assets/js/dd697bad.7125556d.js delete mode 100644 assets/js/dd697bad.81c6ffb9.js create mode 100644 assets/js/debad56b.2b7f41a2.js delete mode 100644 assets/js/debad56b.4a0b6354.js delete mode 100644 assets/js/debf7b3b.15092e15.js create mode 100644 assets/js/debf7b3b.c800f188.js create mode 100644 assets/js/decf5f3b.aa7b642a.js delete mode 100644 assets/js/decf5f3b.b2ef684b.js create mode 100644 assets/js/ded3805b.d56523a7.js delete mode 100644 assets/js/ded3805b.f23cb0ff.js create mode 100644 assets/js/df556f53.4f722245.js delete mode 100644 assets/js/df556f53.9f8623a5.js create mode 100644 assets/js/dfd0c61c.f764b97a.js create mode 100644 assets/js/e0827474.2bcff7f1.js delete mode 100644 assets/js/e0827474.cbc0a376.js create mode 100644 assets/js/e0af8c55.8ca17dc0.js delete mode 100644 assets/js/e0af8c55.c8ae87c8.js create mode 100644 assets/js/e0d2da0e.2bf5fdc2.js delete mode 100644 assets/js/e0d2da0e.729c3d0b.js delete mode 100644 assets/js/e0e5f1df.d565dcaf.js create mode 100644 assets/js/e0e5f1df.e34392c9.js delete mode 100644 assets/js/e113796f.baf9c36e.js create mode 100644 assets/js/e113796f.f18fe52d.js create mode 100644 assets/js/e13c5473.20a756a6.js delete mode 100644 assets/js/e13c5473.9dc4d19d.js create mode 100644 assets/js/e13e97ed.cc93bbf2.js delete mode 100644 assets/js/e13e97ed.d82eb3be.js delete mode 100644 assets/js/e1492825.0e1d098e.js create mode 100644 assets/js/e1492825.1a398f6c.js delete mode 100644 assets/js/e1957427.488c5b0f.js create mode 100644 assets/js/e1957427.62cc2f27.js create mode 100644 assets/js/e1b01fca.c4e24a49.js delete mode 100644 assets/js/e1b01fca.d13b43a9.js delete mode 100644 assets/js/e1c2e776.661131c0.js create mode 100644 assets/js/e1c2e776.cf5e4bee.js delete mode 100644 assets/js/e1d07e5f.6056ce7c.js create mode 100644 assets/js/e1d07e5f.f169c77f.js create mode 100644 assets/js/e2266027.ca7058b6.js delete mode 100644 assets/js/e2266027.cc89f3c4.js create mode 100644 assets/js/e23da508.5a3fcf75.js delete mode 100644 assets/js/e3683d7e.77fb0b24.js create mode 100644 assets/js/e3683d7e.d7d535cc.js create mode 100644 assets/js/e49f040d.8979c140.js delete mode 100644 assets/js/e49f040d.d9e088c1.js create mode 100644 assets/js/e519cd9e.309bf578.js delete mode 100644 assets/js/e519cd9e.f17d13b9.js create mode 100644 assets/js/e54a7808.54e8c609.js delete mode 100644 assets/js/e54a7808.bd165c91.js create mode 100644 assets/js/e57a39f4.a7d4aa52.js delete mode 100644 assets/js/e57a39f4.cd4ad4f7.js create mode 100644 assets/js/e5dee6fa.1f05e79f.js delete mode 100644 assets/js/e5dee6fa.e9235b5a.js delete mode 100644 assets/js/e724aa0c.3d0a2fd2.js create mode 100644 assets/js/e724aa0c.fe902d00.js create mode 100644 assets/js/e795d793.a596b0d1.js delete mode 100644 assets/js/e795d793.d3b3da14.js rename assets/js/{20c8a971.1235b424.js => e7c319aa.21b7fb82.js} (95%) delete mode 100644 assets/js/e7c319aa.66922067.js create mode 100644 assets/js/e8203627.a21ade88.js delete mode 100644 assets/js/e8203627.add3bd8a.js delete mode 100644 assets/js/e85b2b68.3cbf6efe.js create mode 100644 assets/js/e85b2b68.b2bc0b8c.js delete mode 100644 assets/js/ea6b699b.28b42de3.js create mode 100644 assets/js/ea6b699b.c3fd2eee.js create mode 100644 assets/js/eaf7dfdf.1349bc60.js delete mode 100644 assets/js/eaf7dfdf.3a1b03a5.js delete mode 100644 assets/js/ec307c91.81ac9899.js create mode 100644 assets/js/ec307c91.dfc47eb0.js delete mode 100644 assets/js/ec7c2dfb.4cab3e9d.js create mode 100644 assets/js/ec7c2dfb.e49d045a.js create mode 100644 assets/js/ec9cd171.dc66291f.js delete mode 100644 assets/js/ec9cd171.f04964a0.js delete mode 100644 assets/js/ec9e4b3c.302ca95b.js create mode 100644 assets/js/ec9e4b3c.7dbd47ed.js create mode 100644 assets/js/ecd40885.7c9b3f43.js delete mode 100644 assets/js/ecd40885.82daba91.js create mode 100644 assets/js/ecfe08ed.20988fa1.js delete mode 100644 assets/js/ecfe08ed.3807b562.js delete mode 100644 assets/js/ee05e1f4.0cdb4c5f.js create mode 100644 assets/js/ee05e1f4.feb956d4.js delete mode 100644 assets/js/eeb154ce.a4ba2e31.js create mode 100644 assets/js/eeb154ce.c464f72d.js create mode 100644 assets/js/ef17e2db.439b7677.js delete mode 100644 assets/js/ef17e2db.4b09772d.js create mode 100644 assets/js/ef350d98.156b5372.js delete mode 100644 assets/js/ef350d98.b875fb01.js delete mode 100644 assets/js/ef5bbb0b.8e432cc4.js create mode 100644 assets/js/ef5bbb0b.be1d053d.js rename assets/js/{53346373.cc2df6da.js => f047be76.73e98be6.js} (88%) delete mode 100644 assets/js/f047be76.b24cb54d.js delete mode 100644 assets/js/f0824f11.3d3a3486.js create mode 100644 assets/js/f0824f11.4eaff4be.js delete mode 100644 assets/js/f0bcf997.013d8e2f.js create mode 100644 assets/js/f0bcf997.2c4c3aff.js delete mode 100644 assets/js/f0f74909.116e6b8b.js create mode 100644 assets/js/f0f74909.7456614c.js delete mode 100644 assets/js/f113d671.7d9d0b0b.js create mode 100644 assets/js/f113d671.c6a39c0f.js delete mode 100644 assets/js/f12166ea.614e5dbd.js create mode 100644 assets/js/f12166ea.897ee306.js create mode 100644 assets/js/f1c8adb6.839ab4dd.js delete mode 100644 assets/js/f1c8adb6.bd7bb9ed.js create mode 100644 assets/js/f211d1a3.30aa1881.js delete mode 100644 assets/js/f211d1a3.f5dc7ca7.js delete mode 100644 assets/js/f22722eb.1f48053d.js create mode 100644 assets/js/f22722eb.dd45234b.js create mode 100644 assets/js/f28290c6.d3d7d8fe.js delete mode 100644 assets/js/f28290c6.f4917cc4.js create mode 100644 assets/js/f2a39581.694ea258.js delete mode 100644 assets/js/f2a39581.f87e4643.js delete mode 100644 assets/js/f2be4710.6d180ae7.js create mode 100644 assets/js/f2be4710.763f9ee7.js delete mode 100644 assets/js/f2ce7b58.2ba3cbfe.js create mode 100644 assets/js/f2ce7b58.ccc2c689.js delete mode 100644 assets/js/f331dae8.563330d5.js create mode 100644 assets/js/f331dae8.c054beb4.js delete mode 100644 assets/js/f3ada91d.629c00a7.js create mode 100644 assets/js/f3ada91d.d2c1364d.js create mode 100644 assets/js/f44e39f1.9beb3af5.js delete mode 100644 assets/js/f44e39f1.c99e836d.js create mode 100644 assets/js/f4ade6b7.1936d66f.js delete mode 100644 assets/js/f4ade6b7.f165da54.js delete mode 100644 assets/js/f57f08dc.47ac888a.js create mode 100644 assets/js/f57f08dc.b524e515.js create mode 100644 assets/js/f5b1c9e7.adb2fdd8.js delete mode 100644 assets/js/f5b1c9e7.e19d0d75.js delete mode 100644 assets/js/f6c54c06.7794838f.js create mode 100644 assets/js/f6c54c06.d6941501.js create mode 100644 assets/js/f6c94d23.993406df.js delete mode 100644 assets/js/f6c94d23.e44ffdd8.js create mode 100644 assets/js/f6f4b6e7.5ac3be77.js delete mode 100644 assets/js/f6f4b6e7.ed5e973a.js delete mode 100644 assets/js/f756729a.e98b83ec.js create mode 100644 assets/js/f756729a.f9d98116.js delete mode 100644 assets/js/f79beca4.4aed32b0.js create mode 100644 assets/js/f79beca4.e6deb386.js create mode 100644 assets/js/f7ff1d73.0419a74c.js delete mode 100644 assets/js/f7ff1d73.ce4e9ccb.js create mode 100644 assets/js/f80e1b1f.0fcf9dff.js delete mode 100644 assets/js/f80e1b1f.b85ab3ad.js create mode 100644 assets/js/f838c6f5.77827f68.js delete mode 100644 assets/js/f838c6f5.c86f13b3.js create mode 100644 assets/js/f83908bc.15827dcc.js delete mode 100644 assets/js/f83908bc.f207c64b.js delete mode 100644 assets/js/f856d65b.03d1876d.js create mode 100644 assets/js/f856d65b.6991b249.js delete mode 100644 assets/js/f8c10ed2.382cf68d.js create mode 100644 assets/js/f8c10ed2.7fedcf65.js create mode 100644 assets/js/f8d246d6.b7c0caab.js delete mode 100644 assets/js/f8d246d6.fc7d6a61.js delete mode 100644 assets/js/f8e2a94e.35a998b9.js create mode 100644 assets/js/f8e2a94e.e8bbee68.js create mode 100644 assets/js/f91fb9d4.17a61b02.js delete mode 100644 assets/js/f91fb9d4.f334db20.js delete mode 100644 assets/js/f9a81682.7234eec2.js create mode 100644 assets/js/f9a81682.f7f2d935.js create mode 100644 assets/js/fa425188.41feb8da.js delete mode 100644 assets/js/fa425188.6cf49621.js delete mode 100644 assets/js/fa6830dd.ac80adf6.js rename assets/js/{19099ebb.b2cd8e52.js => fa6830dd.b6f324cb.js} (88%) create mode 100644 assets/js/fb61b539.20f561fa.js delete mode 100644 assets/js/fba79747.d1182591.js create mode 100644 assets/js/fba79747.eac221dd.js delete mode 100644 assets/js/fbb98df9.12e20a97.js create mode 100644 assets/js/fbb98df9.e3268bb8.js delete mode 100644 assets/js/fbdd80d3.6befcd7f.js create mode 100644 assets/js/fbdd80d3.aa985285.js create mode 100644 assets/js/fbfd0f42.26abc53c.js delete mode 100644 assets/js/fbfd0f42.f06087a3.js create mode 100644 assets/js/fd0ee3c6.b2a24103.js rename assets/js/{dfd0c61c.1c2ace93.js => fd890d09.42e11d81.js} (88%) delete mode 100644 assets/js/fd890d09.82a644ed.js create mode 100644 assets/js/fda8383b.756ab3f4.js delete mode 100644 assets/js/fda8383b.94e04d32.js create mode 100644 assets/js/fddea1d0.3b495087.js delete mode 100644 assets/js/fddea1d0.e17c3a78.js create mode 100644 assets/js/fdef3022.17db9d38.js delete mode 100644 assets/js/fdef3022.378b56f9.js create mode 100644 assets/js/fdfe87c5.35a0378c.js delete mode 100644 assets/js/fdfe87c5.6ba6bb75.js delete mode 100644 assets/js/fe1988be.58275a38.js create mode 100644 assets/js/fe1988be.b190ba6a.js create mode 100644 assets/js/fe41fb76.2f6af41e.js delete mode 100644 assets/js/fe41fb76.f708ab5c.js create mode 100644 assets/js/ff2e33f3.ce4ac25e.js delete mode 100644 assets/js/ff2e33f3.ed657153.js delete mode 100644 assets/js/main.5e3b2c86.js create mode 100644 assets/js/main.6aef9bdc.js rename assets/js/{main.5e3b2c86.js.LICENSE.txt => main.6aef9bdc.js.LICENSE.txt} (100%) rename assets/js/{runtime~main.36102bb2.js => runtime~main.a80a79be.js} (62%) diff --git a/404.html b/404.html index e88f0d54fc..bff7e57326 100644 --- a/404.html +++ b/404.html @@ -2,10 +2,10 @@ - -Page Not Found | Richie - - + +Page Not Found | Richie + +
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

diff --git a/assets/css/styles.bc5d7c07.css b/assets/css/styles.c29f85f3.css similarity index 98% rename from assets/css/styles.bc5d7c07.css rename to assets/css/styles.c29f85f3.css index 3f54deeb30..ea3451049b 100644 --- a/assets/css/styles.bc5d7c07.css +++ b/assets/css/styles.c29f85f3.css @@ -1 +1 @@ -.col,.container{padding:0 var(--ifm-spacing-horizontal);width:100%}.markdown>h2,.markdown>h3,.markdown>h4,.markdown>h5,.markdown>h6{margin-bottom:calc(var(--ifm-heading-vertical-rhythm-bottom)*var(--ifm-leading))}.markdown li,body{word-wrap:break-word}body,ol ol,ol ul,ul ol,ul ul{margin:0}pre,table{overflow:auto}blockquote,pre{margin:0 0 var(--ifm-spacing-vertical)}.breadcrumbs__link,.button{transition-timing-function:var(--ifm-transition-timing-default)}.button,code{vertical-align:middle}.button--outline.button--active,.button--outline:active,.button--outline:hover,:root{--ifm-button-color:var(--ifm-font-color-base-inverse)}.menu__link:hover,a{transition:color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.navbar--dark,:root{--ifm-navbar-link-hover-color:var(--ifm-color-primary)}.menu,.navbar-sidebar{overflow-x:hidden}:root,html[data-theme=dark]{--ifm-color-emphasis-500:var(--ifm-color-gray-500)}:root,[data-theme=dark]:root{--ifm-section-alt3-background:grey}.toggleButton_gllP,html{-webkit-tap-highlight-color:transparent}.clean-list,.containsTaskList_mC6p,.details_lb9f>summary,.dropdown__menu,.menu__list{list-style:none}:root{--ifm-color-scheme:light;--ifm-dark-value:10%;--ifm-darker-value:15%;--ifm-darkest-value:30%;--ifm-light-value:15%;--ifm-lighter-value:30%;--ifm-lightest-value:50%;--ifm-contrast-background-value:90%;--ifm-contrast-foreground-value:70%;--ifm-contrast-background-dark-value:70%;--ifm-contrast-foreground-dark-value:90%;--ifm-color-primary:#3578e5;--ifm-color-secondary:#ebedf0;--ifm-color-success:#00a400;--ifm-color-info:#54c7ec;--ifm-color-warning:#ffba00;--ifm-color-danger:#fa383e;--ifm-color-primary-dark:#306cce;--ifm-color-primary-darker:#2d66c3;--ifm-color-primary-darkest:#2554a0;--ifm-color-primary-light:#538ce9;--ifm-color-primary-lighter:#72a1ed;--ifm-color-primary-lightest:#9abcf2;--ifm-color-primary-contrast-background:#ebf2fc;--ifm-color-primary-contrast-foreground:#102445;--ifm-color-secondary-dark:#d4d5d8;--ifm-color-secondary-darker:#c8c9cc;--ifm-color-secondary-darkest:#a4a6a8;--ifm-color-secondary-light:#eef0f2;--ifm-color-secondary-lighter:#f1f2f5;--ifm-color-secondary-lightest:#f5f6f8;--ifm-color-secondary-contrast-background:#fdfdfe;--ifm-color-secondary-contrast-foreground:#474748;--ifm-color-success-dark:#009400;--ifm-color-success-darker:#008b00;--ifm-color-success-darkest:#007300;--ifm-color-success-light:#26b226;--ifm-color-success-lighter:#4dbf4d;--ifm-color-success-lightest:#80d280;--ifm-color-success-contrast-background:#e6f6e6;--ifm-color-success-contrast-foreground:#003100;--ifm-color-info-dark:#4cb3d4;--ifm-color-info-darker:#47a9c9;--ifm-color-info-darkest:#3b8ba5;--ifm-color-info-light:#6ecfef;--ifm-color-info-lighter:#87d8f2;--ifm-color-info-lightest:#aae3f6;--ifm-color-info-contrast-background:#eef9fd;--ifm-color-info-contrast-foreground:#193c47;--ifm-color-warning-dark:#e6a700;--ifm-color-warning-darker:#d99e00;--ifm-color-warning-darkest:#b38200;--ifm-color-warning-light:#ffc426;--ifm-color-warning-lighter:#ffcf4d;--ifm-color-warning-lightest:#ffdd80;--ifm-color-warning-contrast-background:#fff8e6;--ifm-color-warning-contrast-foreground:#4d3800;--ifm-color-danger-dark:#e13238;--ifm-color-danger-darker:#d53035;--ifm-color-danger-darkest:#af272b;--ifm-color-danger-light:#fb565b;--ifm-color-danger-lighter:#fb7478;--ifm-color-danger-lightest:#fd9c9f;--ifm-color-danger-contrast-background:#ffebec;--ifm-color-danger-contrast-foreground:#4b1113;--ifm-color-white:#fff;--ifm-color-black:#000;--ifm-color-gray-0:var(--ifm-color-white);--ifm-color-gray-100:#f5f6f7;--ifm-color-gray-200:#ebedf0;--ifm-color-gray-300:#dadde1;--ifm-color-gray-400:#ccd0d5;--ifm-color-gray-500:#bec3c9;--ifm-color-gray-600:#8d949e;--ifm-color-gray-700:#606770;--ifm-color-gray-800:#444950;--ifm-color-gray-900:#1c1e21;--ifm-color-gray-1000:var(--ifm-color-black);--ifm-color-emphasis-0:var(--ifm-color-gray-0);--ifm-color-emphasis-100:var(--ifm-color-gray-100);--ifm-color-emphasis-200:var(--ifm-color-gray-200);--ifm-color-emphasis-300:var(--ifm-color-gray-300);--ifm-color-emphasis-400:var(--ifm-color-gray-400);--ifm-color-emphasis-600:var(--ifm-color-gray-600);--ifm-color-emphasis-700:var(--ifm-color-gray-700);--ifm-color-emphasis-800:var(--ifm-color-gray-800);--ifm-color-emphasis-900:var(--ifm-color-gray-900);--ifm-color-emphasis-1000:var(--ifm-color-gray-1000);--ifm-color-content:var(--ifm-color-emphasis-900);--ifm-color-content-inverse:var(--ifm-color-emphasis-0);--ifm-color-content-secondary:#525860;--ifm-background-color:transparent;--ifm-background-surface-color:var(--ifm-color-content-inverse);--ifm-global-border-width:1px;--ifm-global-radius:0.4rem;--ifm-hover-overlay:rgba(0,0,0,.05);--ifm-font-color-base:var(--ifm-color-content);--ifm-font-color-base-inverse:var(--ifm-color-content-inverse);--ifm-font-color-secondary:var(--ifm-color-content-secondary);--ifm-font-family-base:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--ifm-font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--ifm-font-size-base:100%;--ifm-font-weight-light:300;--ifm-font-weight-normal:400;--ifm-font-weight-semibold:500;--ifm-font-weight-bold:700;--ifm-font-weight-base:var(--ifm-font-weight-normal);--ifm-line-height-base:1.65;--ifm-global-spacing:1rem;--ifm-spacing-vertical:var(--ifm-global-spacing);--ifm-spacing-horizontal:var(--ifm-global-spacing);--ifm-transition-fast:200ms;--ifm-transition-slow:400ms;--ifm-transition-timing-default:cubic-bezier(0.08,0.52,0.52,1);--ifm-global-shadow-lw:0 1px 2px 0 rgba(0,0,0,.1);--ifm-global-shadow-md:0 5px 40px rgba(0,0,0,.2);--ifm-global-shadow-tl:0 12px 28px 0 rgba(0,0,0,.2),0 2px 4px 0 rgba(0,0,0,.1);--ifm-z-index-dropdown:100;--ifm-z-index-fixed:200;--ifm-z-index-overlay:400;--ifm-container-width:1140px;--ifm-container-width-xl:1320px;--ifm-code-background:#f6f7f8;--ifm-code-border-radius:var(--ifm-global-radius);--ifm-code-font-size:90%;--ifm-code-padding-horizontal:0.1rem;--ifm-code-padding-vertical:0.1rem;--ifm-pre-background:var(--ifm-code-background);--ifm-pre-border-radius:var(--ifm-code-border-radius);--ifm-pre-color:inherit;--ifm-pre-line-height:1.45;--ifm-pre-padding:1rem;--ifm-heading-color:inherit;--ifm-heading-margin-top:0;--ifm-heading-margin-bottom:var(--ifm-spacing-vertical);--ifm-heading-font-family:var(--ifm-font-family-base);--ifm-heading-font-weight:var(--ifm-font-weight-bold);--ifm-heading-line-height:1.25;--ifm-h1-font-size:2rem;--ifm-h2-font-size:1.5rem;--ifm-h3-font-size:1.25rem;--ifm-h4-font-size:1rem;--ifm-h5-font-size:0.875rem;--ifm-h6-font-size:0.85rem;--ifm-image-alignment-padding:1.25rem;--ifm-leading-desktop:1.25;--ifm-leading:calc(var(--ifm-leading-desktop)*1rem);--ifm-list-left-padding:2rem;--ifm-list-margin:1rem;--ifm-list-item-margin:0.25rem;--ifm-list-paragraph-margin:1rem;--ifm-table-cell-padding:0.75rem;--ifm-table-background:transparent;--ifm-table-stripe-background:rgba(0,0,0,.03);--ifm-table-border-width:1px;--ifm-table-border-color:var(--ifm-color-emphasis-300);--ifm-table-head-background:inherit;--ifm-table-head-color:inherit;--ifm-table-head-font-weight:var(--ifm-font-weight-bold);--ifm-table-cell-color:inherit;--ifm-link-color:var(--ifm-color-primary);--ifm-link-decoration:none;--ifm-link-hover-color:var(--ifm-link-color);--ifm-link-hover-decoration:underline;--ifm-paragraph-margin-bottom:var(--ifm-leading);--ifm-blockquote-font-size:var(--ifm-font-size-base);--ifm-blockquote-border-left-width:2px;--ifm-blockquote-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-blockquote-padding-vertical:0;--ifm-blockquote-shadow:none;--ifm-blockquote-color:var(--ifm-color-emphasis-800);--ifm-blockquote-border-color:var(--ifm-color-emphasis-300);--ifm-hr-background-color:var(--ifm-color-emphasis-500);--ifm-hr-height:1px;--ifm-hr-margin-vertical:1.5rem;--ifm-scrollbar-size:7px;--ifm-scrollbar-track-background-color:#f1f1f1;--ifm-scrollbar-thumb-background-color:silver;--ifm-scrollbar-thumb-hover-background-color:#a7a7a7;--ifm-alert-background-color:inherit;--ifm-alert-border-color:inherit;--ifm-alert-border-radius:var(--ifm-global-radius);--ifm-alert-border-width:0px;--ifm-alert-border-left-width:5px;--ifm-alert-color:var(--ifm-font-color-base);--ifm-alert-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-alert-padding-vertical:var(--ifm-spacing-vertical);--ifm-alert-shadow:var(--ifm-global-shadow-lw);--ifm-avatar-intro-margin:1rem;--ifm-avatar-intro-alignment:inherit;--ifm-avatar-photo-size:3rem;--ifm-badge-background-color:inherit;--ifm-badge-border-color:inherit;--ifm-badge-border-radius:var(--ifm-global-radius);--ifm-badge-border-width:var(--ifm-global-border-width);--ifm-badge-color:var(--ifm-color-white);--ifm-badge-padding-horizontal:calc(var(--ifm-spacing-horizontal)*0.5);--ifm-badge-padding-vertical:calc(var(--ifm-spacing-vertical)*0.25);--ifm-breadcrumb-border-radius:1.5rem;--ifm-breadcrumb-spacing:0.5rem;--ifm-breadcrumb-color-active:var(--ifm-color-primary);--ifm-breadcrumb-item-background-active:var(--ifm-hover-overlay);--ifm-breadcrumb-padding-horizontal:0.8rem;--ifm-breadcrumb-padding-vertical:0.4rem;--ifm-breadcrumb-size-multiplier:1;--ifm-breadcrumb-separator:url('data:image/svg+xml;utf8,');--ifm-breadcrumb-separator-filter:none;--ifm-breadcrumb-separator-size:0.5rem;--ifm-breadcrumb-separator-size-multiplier:1.25;--ifm-button-background-color:inherit;--ifm-button-border-color:var(--ifm-button-background-color);--ifm-button-border-width:var(--ifm-global-border-width);--ifm-button-font-weight:var(--ifm-font-weight-bold);--ifm-button-padding-horizontal:1.5rem;--ifm-button-padding-vertical:0.375rem;--ifm-button-size-multiplier:1;--ifm-button-transition-duration:var(--ifm-transition-fast);--ifm-button-border-radius:calc(var(--ifm-global-radius)*var(--ifm-button-size-multiplier));--ifm-button-group-spacing:2px;--ifm-card-background-color:var(--ifm-background-surface-color);--ifm-card-border-radius:calc(var(--ifm-global-radius)*2);--ifm-card-horizontal-spacing:var(--ifm-global-spacing);--ifm-card-vertical-spacing:var(--ifm-global-spacing);--ifm-toc-border-color:var(--ifm-color-emphasis-300);--ifm-toc-link-color:var(--ifm-color-content-secondary);--ifm-toc-padding-vertical:0.5rem;--ifm-toc-padding-horizontal:0.5rem;--ifm-dropdown-background-color:var(--ifm-background-surface-color);--ifm-dropdown-font-weight:var(--ifm-font-weight-semibold);--ifm-dropdown-link-color:var(--ifm-font-color-base);--ifm-dropdown-hover-background-color:var(--ifm-hover-overlay);--ifm-footer-background-color:var(--ifm-color-emphasis-100);--ifm-footer-color:inherit;--ifm-footer-link-color:var(--ifm-color-emphasis-700);--ifm-footer-link-hover-color:var(--ifm-color-primary);--ifm-footer-link-horizontal-spacing:0.5rem;--ifm-footer-padding-horizontal:calc(var(--ifm-spacing-horizontal)*2);--ifm-footer-padding-vertical:calc(var(--ifm-spacing-vertical)*2);--ifm-footer-title-color:inherit;--ifm-footer-logo-max-width:min(30rem,90vw);--ifm-hero-background-color:var(--ifm-background-surface-color);--ifm-hero-text-color:var(--ifm-color-emphasis-800);--ifm-menu-color:var(--ifm-color-emphasis-700);--ifm-menu-color-active:var(--ifm-color-primary);--ifm-menu-color-background-active:var(--ifm-hover-overlay);--ifm-menu-color-background-hover:var(--ifm-hover-overlay);--ifm-menu-link-padding-horizontal:0.75rem;--ifm-menu-link-padding-vertical:0.375rem;--ifm-menu-link-sublist-icon:url('data:image/svg+xml;utf8,');--ifm-menu-link-sublist-icon-filter:none;--ifm-navbar-background-color:var(--ifm-background-surface-color);--ifm-navbar-height:3.75rem;--ifm-navbar-item-padding-horizontal:0.75rem;--ifm-navbar-item-padding-vertical:0.25rem;--ifm-navbar-link-color:var(--ifm-font-color-base);--ifm-navbar-link-active-color:var(--ifm-link-color);--ifm-navbar-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-navbar-padding-vertical:calc(var(--ifm-spacing-vertical)*0.5);--ifm-navbar-shadow:var(--ifm-global-shadow-lw);--ifm-navbar-search-input-background-color:var(--ifm-color-emphasis-200);--ifm-navbar-search-input-color:var(--ifm-color-emphasis-800);--ifm-navbar-search-input-placeholder-color:var(--ifm-color-emphasis-500);--ifm-navbar-search-input-icon:url('data:image/svg+xml;utf8,');--ifm-navbar-sidebar-width:83vw;--ifm-pagination-border-radius:var(--ifm-global-radius);--ifm-pagination-color-active:var(--ifm-color-primary);--ifm-pagination-font-size:1rem;--ifm-pagination-item-active-background:var(--ifm-hover-overlay);--ifm-pagination-page-spacing:0.2em;--ifm-pagination-padding-horizontal:calc(var(--ifm-spacing-horizontal)*1);--ifm-pagination-padding-vertical:calc(var(--ifm-spacing-vertical)*0.25);--ifm-pagination-nav-border-radius:var(--ifm-global-radius);--ifm-pagination-nav-color-hover:var(--ifm-color-primary);--ifm-pills-color-active:var(--ifm-color-primary);--ifm-pills-color-background-active:var(--ifm-hover-overlay);--ifm-pills-spacing:0.125rem;--ifm-tabs-color:var(--ifm-font-color-secondary);--ifm-tabs-color-active:var(--ifm-color-primary);--ifm-tabs-color-active-border:var(--ifm-tabs-color-active);--ifm-tabs-padding-horizontal:1rem;--ifm-tabs-padding-vertical:1rem}.badge--danger,.badge--info,.badge--primary,.badge--secondary,.badge--success,.badge--warning{--ifm-badge-border-color:var(--ifm-badge-background-color)}.button--link,.button--outline{--ifm-button-background-color:transparent}*{box-sizing:border-box}html{-webkit-font-smoothing:antialiased;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;text-size-adjust:100%;background-color:var(--ifm-background-color);color:var(--ifm-font-color-base);color-scheme:var(--ifm-color-scheme);font:var(--ifm-font-size-base)/var(--ifm-line-height-base) var(--ifm-font-family-base);text-rendering:optimizelegibility}iframe{border:0;color-scheme:auto}.container{margin:0 auto;max-width:var(--ifm-container-width)}.container--fluid{max-width:inherit}.row{display:flex;flex-wrap:wrap;margin:0 calc(var(--ifm-spacing-horizontal)*-1)}.margin-bottom--none,.margin-vert--none,.markdown>:last-child{margin-bottom:0!important}.margin-top--none,.margin-vert--none{margin-top:0!important}.row--no-gutters{margin-left:0;margin-right:0}.margin-horiz--none,.margin-right--none{margin-right:0!important}.row--no-gutters>.col{padding-left:0;padding-right:0}.row--align-top{align-items:flex-start}.row--align-bottom{align-items:flex-end}.menuExternalLink_NmtK,.row--align-center{align-items:center}.row--align-stretch{align-items:stretch}.row--align-baseline{align-items:baseline}.col{--ifm-col-width:100%;flex:1 0;margin-left:0;max-width:var(--ifm-col-width)}.padding-bottom--none,.padding-vert--none{padding-bottom:0!important}.padding-top--none,.padding-vert--none{padding-top:0!important}.padding-horiz--none,.padding-left--none{padding-left:0!important}.padding-horiz--none,.padding-right--none{padding-right:0!important}.col[class*=col--]{flex:0 0 var(--ifm-col-width)}.col--1{--ifm-col-width:8.33333%}.col--offset-1{margin-left:8.33333%}.col--2{--ifm-col-width:16.66667%}.col--offset-2{margin-left:16.66667%}.col--3{--ifm-col-width:25%}.col--offset-3{margin-left:25%}.col--4{--ifm-col-width:33.33333%}.col--offset-4{margin-left:33.33333%}.col--5{--ifm-col-width:41.66667%}.col--offset-5{margin-left:41.66667%}.col--6{--ifm-col-width:50%}.col--offset-6{margin-left:50%}.col--7{--ifm-col-width:58.33333%}.col--offset-7{margin-left:58.33333%}.col--8{--ifm-col-width:66.66667%}.col--offset-8{margin-left:66.66667%}.col--9{--ifm-col-width:75%}.col--offset-9{margin-left:75%}.col--10{--ifm-col-width:83.33333%}.col--offset-10{margin-left:83.33333%}.col--11{--ifm-col-width:91.66667%}.col--offset-11{margin-left:91.66667%}.col--12{--ifm-col-width:100%}.col--offset-12{margin-left:100%}.margin-horiz--none,.margin-left--none{margin-left:0!important}.margin--none{margin:0!important}.margin-bottom--xs,.margin-vert--xs{margin-bottom:.25rem!important}.margin-top--xs,.margin-vert--xs{margin-top:.25rem!important}.margin-horiz--xs,.margin-left--xs{margin-left:.25rem!important}.margin-horiz--xs,.margin-right--xs{margin-right:.25rem!important}.margin--xs{margin:.25rem!important}.margin-bottom--sm,.margin-vert--sm{margin-bottom:.5rem!important}.margin-top--sm,.margin-vert--sm{margin-top:.5rem!important}.margin-horiz--sm,.margin-left--sm{margin-left:.5rem!important}.margin-horiz--sm,.margin-right--sm{margin-right:.5rem!important}.margin--sm{margin:.5rem!important}.margin-bottom--md,.margin-vert--md{margin-bottom:1rem!important}.margin-top--md,.margin-vert--md{margin-top:1rem!important}.margin-horiz--md,.margin-left--md{margin-left:1rem!important}.margin-horiz--md,.margin-right--md{margin-right:1rem!important}.margin--md{margin:1rem!important}.margin-bottom--lg,.margin-vert--lg{margin-bottom:2rem!important}.margin-top--lg,.margin-vert--lg{margin-top:2rem!important}.margin-horiz--lg,.margin-left--lg{margin-left:2rem!important}.margin-horiz--lg,.margin-right--lg{margin-right:2rem!important}.margin--lg{margin:2rem!important}.margin-bottom--xl,.margin-vert--xl{margin-bottom:5rem!important}.margin-top--xl,.margin-vert--xl{margin-top:5rem!important}.margin-horiz--xl,.margin-left--xl{margin-left:5rem!important}.margin-horiz--xl,.margin-right--xl{margin-right:5rem!important}.margin--xl{margin:5rem!important}.padding--none{padding:0!important}.padding-bottom--xs,.padding-vert--xs{padding-bottom:.25rem!important}.padding-top--xs,.padding-vert--xs{padding-top:.25rem!important}.padding-horiz--xs,.padding-left--xs{padding-left:.25rem!important}.padding-horiz--xs,.padding-right--xs{padding-right:.25rem!important}.padding--xs{padding:.25rem!important}.padding-bottom--sm,.padding-vert--sm{padding-bottom:.5rem!important}.padding-top--sm,.padding-vert--sm{padding-top:.5rem!important}.padding-horiz--sm,.padding-left--sm{padding-left:.5rem!important}.padding-horiz--sm,.padding-right--sm{padding-right:.5rem!important}.padding--sm{padding:.5rem!important}.padding-bottom--md,.padding-vert--md{padding-bottom:1rem!important}.padding-top--md,.padding-vert--md{padding-top:1rem!important}.padding-horiz--md,.padding-left--md{padding-left:1rem!important}.padding-horiz--md,.padding-right--md{padding-right:1rem!important}.padding--md{padding:1rem!important}.padding-bottom--lg,.padding-vert--lg{padding-bottom:2rem!important}.padding-top--lg,.padding-vert--lg{padding-top:2rem!important}.padding-horiz--lg,.padding-left--lg{padding-left:2rem!important}.padding-horiz--lg,.padding-right--lg{padding-right:2rem!important}.padding--lg{padding:2rem!important}.padding-bottom--xl,.padding-vert--xl{padding-bottom:5rem!important}.padding-top--xl,.padding-vert--xl{padding-top:5rem!important}.padding-horiz--xl,.padding-left--xl{padding-left:5rem!important}.padding-horiz--xl,.padding-right--xl{padding-right:5rem!important}.padding--xl{padding:5rem!important}code{background-color:var(--ifm-code-background);border:.1rem solid rgba(0,0,0,.1);border-radius:var(--ifm-code-border-radius);font-family:var(--ifm-font-family-monospace);font-size:var(--ifm-code-font-size);padding:var(--ifm-code-padding-vertical) var(--ifm-code-padding-horizontal)}a code{color:inherit}pre{background-color:var(--ifm-pre-background);border-radius:var(--ifm-pre-border-radius);color:var(--ifm-pre-color);font:var(--ifm-code-font-size)/var(--ifm-pre-line-height) var(--ifm-font-family-monospace);padding:var(--ifm-pre-padding)}pre code{background-color:transparent;border:none;font-size:100%;line-height:inherit;padding:0}kbd{background-color:var(--ifm-color-emphasis-0);border:1px solid var(--ifm-color-emphasis-400);border-radius:.2rem;box-shadow:inset 0 -1px 0 var(--ifm-color-emphasis-400);color:var(--ifm-color-emphasis-800);font:80% var(--ifm-font-family-monospace);padding:.15rem .3rem}h1,h2,h3,h4,h5,h6{color:var(--ifm-heading-color);font-family:var(--ifm-heading-font-family);font-weight:var(--ifm-heading-font-weight);line-height:var(--ifm-heading-line-height);margin:var(--ifm-heading-margin-top) 0 var(--ifm-heading-margin-bottom) 0}h1{font-size:var(--ifm-h1-font-size)}h2{font-size:var(--ifm-h2-font-size)}h3{font-size:var(--ifm-h3-font-size)}h4{font-size:var(--ifm-h4-font-size)}h5{font-size:var(--ifm-h5-font-size)}h6{font-size:var(--ifm-h6-font-size)}img{max-width:100%}img[align=right]{padding-left:var(--image-alignment-padding)}img[align=left]{padding-right:var(--image-alignment-padding)}.markdown{--ifm-h1-vertical-rhythm-top:3;--ifm-h2-vertical-rhythm-top:2;--ifm-h3-vertical-rhythm-top:1.5;--ifm-heading-vertical-rhythm-top:1.25;--ifm-h1-vertical-rhythm-bottom:1.25;--ifm-heading-vertical-rhythm-bottom:1}.markdown:after,.markdown:before{content:"";display:table}.markdown:after{clear:both}.markdown h1:first-child{--ifm-h1-font-size:3rem;margin-bottom:calc(var(--ifm-h1-vertical-rhythm-bottom)*var(--ifm-leading))}.markdown>h2{--ifm-h2-font-size:2rem;margin-top:calc(var(--ifm-h2-vertical-rhythm-top)*var(--ifm-leading))}.markdown>h3{--ifm-h3-font-size:1.5rem;margin-top:calc(var(--ifm-h3-vertical-rhythm-top)*var(--ifm-leading))}.markdown>h4,.markdown>h5,.markdown>h6{margin-top:calc(var(--ifm-heading-vertical-rhythm-top)*var(--ifm-leading))}.markdown>p,.markdown>pre,.markdown>ul{margin-bottom:var(--ifm-leading)}.markdown li>p{margin-top:var(--ifm-list-paragraph-margin)}.markdown li+li{margin-top:var(--ifm-list-item-margin)}ol,ul{margin:0 0 var(--ifm-list-margin);padding-left:var(--ifm-list-left-padding)}ol ol,ul ol{list-style-type:lower-roman}ol ol ol,ol ul ol,ul ol ol,ul ul ol{list-style-type:lower-alpha}table{border-collapse:collapse;display:block;margin-bottom:var(--ifm-spacing-vertical)}table thead tr{border-bottom:2px solid var(--ifm-table-border-color)}table thead,table tr:nth-child(2n){background-color:var(--ifm-table-stripe-background)}table tr{background-color:var(--ifm-table-background);border-top:var(--ifm-table-border-width) solid var(--ifm-table-border-color)}table td,table th{border:var(--ifm-table-border-width) solid var(--ifm-table-border-color);padding:var(--ifm-table-cell-padding)}table th{background-color:var(--ifm-table-head-background);color:var(--ifm-table-head-color);font-weight:var(--ifm-table-head-font-weight)}table td{color:var(--ifm-table-cell-color)}strong{font-weight:var(--ifm-font-weight-bold)}a{color:var(--ifm-link-color);text-decoration:var(--ifm-link-decoration)}a:hover{color:var(--ifm-link-hover-color);text-decoration:var(--ifm-link-hover-decoration)}.button:hover,.text--no-decoration,.text--no-decoration:hover,a:not([href]){text-decoration:none}p{margin:0 0 var(--ifm-paragraph-margin-bottom);max-width:560px}blockquote{border-left:var(--ifm-blockquote-border-left-width) solid var(--ifm-blockquote-border-color);box-shadow:var(--ifm-blockquote-shadow);color:var(--ifm-blockquote-color);font-size:var(--ifm-blockquote-font-size);padding:var(--ifm-blockquote-padding-vertical) var(--ifm-blockquote-padding-horizontal)}blockquote>:first-child{margin-top:0}blockquote>:last-child{margin-bottom:0}hr{background-color:var(--ifm-hr-background-color);border:0;height:var(--ifm-hr-height);margin:var(--ifm-hr-margin-vertical) 0}.shadow--lw{box-shadow:var(--ifm-global-shadow-lw)!important}.shadow--md{box-shadow:var(--ifm-global-shadow-md)!important}.shadow--tl{box-shadow:var(--ifm-global-shadow-tl)!important}.showcase-title,.text--primary,.wordWrapButtonEnabled_EoeP .wordWrapButtonIcon_Bwma{color:var(--ifm-color-primary)}.text--secondary{color:var(--ifm-color-secondary)}.text--success{color:var(--ifm-color-success)}.text--info{color:var(--ifm-color-info)}.text--warning{color:var(--ifm-color-warning)}.text--danger{color:var(--ifm-color-danger)}.text--center{text-align:center}.text--left{text-align:left}.text--justify{text-align:justify}.text--right{text-align:right}.text--capitalize{text-transform:capitalize}.text--lowercase{text-transform:lowercase}.admonitionHeading_Gvgb,.alert__heading,.btn,.text--uppercase{text-transform:uppercase}.text--light{font-weight:var(--ifm-font-weight-light)}.text--normal{font-weight:var(--ifm-font-weight-normal)}.text--semibold{font-weight:var(--ifm-font-weight-semibold)}.text--bold{font-weight:var(--ifm-font-weight-bold)}.text--italic{font-style:italic}.text--truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text--break{word-wrap:break-word!important;word-break:break-word!important}.clean-btn{background:none;border:none;color:inherit;cursor:pointer;font-family:inherit;padding:0}.alert,.alert .close{color:var(--ifm-alert-foreground-color)}.clean-list{padding-left:0}.alert--primary{--ifm-alert-background-color:var(--ifm-color-primary-contrast-background);--ifm-alert-background-color-highlight:rgba(53,120,229,.15);--ifm-alert-foreground-color:var(--ifm-color-primary-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-primary-dark)}.alert--secondary{--ifm-alert-background-color:var(--ifm-color-secondary-contrast-background);--ifm-alert-background-color-highlight:rgba(235,237,240,.15);--ifm-alert-foreground-color:var(--ifm-color-secondary-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-secondary-dark)}.alert--success{--ifm-alert-background-color:var(--ifm-color-success-contrast-background);--ifm-alert-background-color-highlight:rgba(0,164,0,.15);--ifm-alert-foreground-color:var(--ifm-color-success-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-success-dark)}.alert--info{--ifm-alert-background-color:var(--ifm-color-info-contrast-background);--ifm-alert-background-color-highlight:rgba(84,199,236,.15);--ifm-alert-foreground-color:var(--ifm-color-info-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-info-dark)}.alert--warning{--ifm-alert-background-color:var(--ifm-color-warning-contrast-background);--ifm-alert-background-color-highlight:rgba(255,186,0,.15);--ifm-alert-foreground-color:var(--ifm-color-warning-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-warning-dark)}.alert--danger{--ifm-alert-background-color:var(--ifm-color-danger-contrast-background);--ifm-alert-background-color-highlight:rgba(250,56,62,.15);--ifm-alert-foreground-color:var(--ifm-color-danger-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-danger-dark)}.alert{--ifm-code-background:var(--ifm-alert-background-color-highlight);--ifm-link-color:var(--ifm-alert-foreground-color);--ifm-link-hover-color:var(--ifm-alert-foreground-color);--ifm-link-decoration:underline;--ifm-tabs-color:var(--ifm-alert-foreground-color);--ifm-tabs-color-active:var(--ifm-alert-foreground-color);--ifm-tabs-color-active-border:var(--ifm-alert-border-color);background-color:var(--ifm-alert-background-color);border:var(--ifm-alert-border-width) solid var(--ifm-alert-border-color);border-left-width:var(--ifm-alert-border-left-width);border-radius:var(--ifm-alert-border-radius);box-shadow:var(--ifm-alert-shadow);padding:var(--ifm-alert-padding-vertical) var(--ifm-alert-padding-horizontal)}.alert__heading{align-items:center;display:flex;font:700 var(--ifm-h5-font-size)/var(--ifm-heading-line-height) var(--ifm-heading-font-family);margin-bottom:.5rem}.alert__icon{display:inline-flex;margin-right:.4em}.alert__icon svg{fill:var(--ifm-alert-foreground-color);stroke:var(--ifm-alert-foreground-color);stroke-width:0}.alert .close{margin:calc(var(--ifm-alert-padding-vertical)*-1) calc(var(--ifm-alert-padding-horizontal)*-1) 0 0;opacity:.75}.alert .close:focus,.alert .close:hover{opacity:1}.alert a{text-decoration-color:var(--ifm-alert-border-color)}.alert a:hover{text-decoration-thickness:2px}.avatar{-moz-column-gap:var(--ifm-avatar-intro-margin);column-gap:var(--ifm-avatar-intro-margin);display:flex}.avatar__photo{border-radius:50%;display:block;height:var(--ifm-avatar-photo-size);overflow:hidden;width:var(--ifm-avatar-photo-size)}.card--full-height,.navbar__logo img,body,html{height:100%}.avatar__photo--sm{--ifm-avatar-photo-size:2rem}.avatar__photo--lg{--ifm-avatar-photo-size:4rem}.avatar__photo--xl{--ifm-avatar-photo-size:6rem}.avatar__intro{display:flex;flex:1 1;flex-direction:column;justify-content:center;text-align:var(--ifm-avatar-intro-alignment)}.badge,.breadcrumbs__item,.breadcrumbs__link,.button,.dropdown>.navbar__link:after{display:inline-block}.avatar__name{font:700 var(--ifm-h4-font-size)/var(--ifm-heading-line-height) var(--ifm-font-family-base)}.avatar__subtitle{margin-top:.25rem}.avatar--vertical{--ifm-avatar-intro-alignment:center;--ifm-avatar-intro-margin:0.5rem;align-items:center;flex-direction:column}.badge{background-color:var(--ifm-badge-background-color);border:var(--ifm-badge-border-width) solid var(--ifm-badge-border-color);border-radius:var(--ifm-badge-border-radius);color:var(--ifm-badge-color);font-size:75%;font-weight:var(--ifm-font-weight-bold);line-height:1;padding:var(--ifm-badge-padding-vertical) var(--ifm-badge-padding-horizontal)}.badge--primary{--ifm-badge-background-color:var(--ifm-color-primary)}.badge--secondary{--ifm-badge-background-color:var(--ifm-color-secondary);color:var(--ifm-color-black)}.breadcrumbs__link,.button.button--secondary.button--outline:not(.button--active):not(:hover){color:var(--ifm-font-color-base)}.badge--success{--ifm-badge-background-color:var(--ifm-color-success)}.badge--info{--ifm-badge-background-color:var(--ifm-color-info)}.badge--warning{--ifm-badge-background-color:var(--ifm-color-warning)}.badge--danger{--ifm-badge-background-color:var(--ifm-color-danger)}.breadcrumbs{margin-bottom:0;padding-left:0}.breadcrumbs__item:not(:last-child):after{background:var(--ifm-breadcrumb-separator) center;content:" ";display:inline-block;filter:var(--ifm-breadcrumb-separator-filter);height:calc(var(--ifm-breadcrumb-separator-size)*var(--ifm-breadcrumb-size-multiplier)*var(--ifm-breadcrumb-separator-size-multiplier));margin:0 var(--ifm-breadcrumb-spacing);opacity:.5;width:calc(var(--ifm-breadcrumb-separator-size)*var(--ifm-breadcrumb-size-multiplier)*var(--ifm-breadcrumb-separator-size-multiplier))}.breadcrumbs__item--active .breadcrumbs__link{background:var(--ifm-breadcrumb-item-background-active);color:var(--ifm-breadcrumb-color-active)}.breadcrumbs__link{border-radius:var(--ifm-breadcrumb-border-radius);font-size:calc(1rem*var(--ifm-breadcrumb-size-multiplier));padding:calc(var(--ifm-breadcrumb-padding-vertical)*var(--ifm-breadcrumb-size-multiplier)) calc(var(--ifm-breadcrumb-padding-horizontal)*var(--ifm-breadcrumb-size-multiplier));transition-duration:var(--ifm-transition-fast);transition-property:background,color}.breadcrumbs__link:link:hover,.breadcrumbs__link:visited:hover,area[href].breadcrumbs__link:hover{background:var(--ifm-breadcrumb-item-background-active);text-decoration:none}.breadcrumbs__link:-moz-any-link:hover{background:var(--ifm-breadcrumb-item-background-active);text-decoration:none}.breadcrumbs__link:any-link:hover{background:var(--ifm-breadcrumb-item-background-active);text-decoration:none}.breadcrumbs--sm{--ifm-breadcrumb-size-multiplier:0.8}.breadcrumbs--lg{--ifm-breadcrumb-size-multiplier:1.2}.button{background-color:var(--ifm-button-background-color);border:var(--ifm-button-border-width) solid var(--ifm-button-border-color);border-radius:var(--ifm-button-border-radius);cursor:pointer;font-size:calc(.875rem*var(--ifm-button-size-multiplier));font-weight:var(--ifm-button-font-weight);line-height:1.5;padding:calc(var(--ifm-button-padding-vertical)*var(--ifm-button-size-multiplier)) calc(var(--ifm-button-padding-horizontal)*var(--ifm-button-size-multiplier));text-align:center;transition-duration:var(--ifm-button-transition-duration);transition-property:color,background,border-color;-webkit-user-select:none;-moz-user-select:none;user-select:none;white-space:nowrap}.button,.button:hover{color:var(--ifm-button-color)}.button--outline{--ifm-button-color:var(--ifm-button-border-color)}.button--outline:hover{--ifm-button-background-color:var(--ifm-button-border-color)}.button--link{--ifm-button-border-color:transparent;color:var(--ifm-link-color);text-decoration:var(--ifm-link-decoration)}.button--link.button--active,.button--link:active,.button--link:hover{color:var(--ifm-link-hover-color);text-decoration:var(--ifm-link-hover-decoration)}.button.disabled,.button:disabled,.button[disabled]{opacity:.65;pointer-events:none}.button--sm{--ifm-button-size-multiplier:0.8}.button--lg{--ifm-button-size-multiplier:1.35}.button--block{display:block;width:100%}.button.button--secondary{color:var(--ifm-color-gray-900)}:where(.button--primary){--ifm-button-background-color:var(--ifm-color-primary);--ifm-button-border-color:var(--ifm-color-primary)}:where(.button--primary):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-primary-dark);--ifm-button-border-color:var(--ifm-color-primary-dark)}.button--primary.button--active,.button--primary:active{--ifm-button-background-color:var(--ifm-color-primary-darker);--ifm-button-border-color:var(--ifm-color-primary-darker)}:where(.button--secondary){--ifm-button-background-color:var(--ifm-color-secondary);--ifm-button-border-color:var(--ifm-color-secondary)}:where(.button--secondary):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-secondary-dark);--ifm-button-border-color:var(--ifm-color-secondary-dark)}.button--secondary.button--active,.button--secondary:active{--ifm-button-background-color:var(--ifm-color-secondary-darker);--ifm-button-border-color:var(--ifm-color-secondary-darker)}:where(.button--success){--ifm-button-background-color:var(--ifm-color-success);--ifm-button-border-color:var(--ifm-color-success)}:where(.button--success):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-success-dark);--ifm-button-border-color:var(--ifm-color-success-dark)}.button--success.button--active,.button--success:active{--ifm-button-background-color:var(--ifm-color-success-darker);--ifm-button-border-color:var(--ifm-color-success-darker)}:where(.button--info){--ifm-button-background-color:var(--ifm-color-info);--ifm-button-border-color:var(--ifm-color-info)}:where(.button--info):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-info-dark);--ifm-button-border-color:var(--ifm-color-info-dark)}.button--info.button--active,.button--info:active{--ifm-button-background-color:var(--ifm-color-info-darker);--ifm-button-border-color:var(--ifm-color-info-darker)}:where(.button--warning){--ifm-button-background-color:var(--ifm-color-warning);--ifm-button-border-color:var(--ifm-color-warning)}:where(.button--warning):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-warning-dark);--ifm-button-border-color:var(--ifm-color-warning-dark)}.button--warning.button--active,.button--warning:active{--ifm-button-background-color:var(--ifm-color-warning-darker);--ifm-button-border-color:var(--ifm-color-warning-darker)}:where(.button--danger){--ifm-button-background-color:var(--ifm-color-danger);--ifm-button-border-color:var(--ifm-color-danger)}:where(.button--danger):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-danger-dark);--ifm-button-border-color:var(--ifm-color-danger-dark)}.button--danger.button--active,.button--danger:active{--ifm-button-background-color:var(--ifm-color-danger-darker);--ifm-button-border-color:var(--ifm-color-danger-darker)}.button-group{display:inline-flex;gap:var(--ifm-button-group-spacing)}.button-group>.button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.button-group>.button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.button-group--block{display:flex;justify-content:stretch}.button-group--block>.button{flex-grow:1}.card{background-color:var(--ifm-card-background-color);border-radius:var(--ifm-card-border-radius);box-shadow:var(--ifm-global-shadow-lw);display:flex;flex-direction:column;overflow:hidden}.card__image{padding-top:var(--ifm-card-vertical-spacing)}.card__image:first-child{padding-top:0}.card__body,.card__footer,.card__header{padding:var(--ifm-card-vertical-spacing) var(--ifm-card-horizontal-spacing)}.card__body:not(:last-child),.card__footer:not(:last-child),.card__header:not(:last-child){padding-bottom:0}.card__body>:last-child,.card__footer>:last-child,.card__header>:last-child{margin-bottom:0}.card__footer{margin-top:auto}.table-of-contents{font-size:.8rem;margin-bottom:0;padding:var(--ifm-toc-padding-vertical) 0}.table-of-contents,.table-of-contents ul{list-style:none;padding-left:var(--ifm-toc-padding-horizontal)}.table-of-contents li{margin:var(--ifm-toc-padding-vertical) var(--ifm-toc-padding-horizontal)}.table-of-contents__left-border{border-left:1px solid var(--ifm-toc-border-color)}.table-of-contents__link{color:var(--ifm-toc-link-color);display:block}.table-of-contents__link--active,.table-of-contents__link--active code,.table-of-contents__link:hover,.table-of-contents__link:hover code{color:var(--ifm-color-primary);text-decoration:none}.close{color:var(--ifm-color-black);float:right;font-size:1.5rem;font-weight:var(--ifm-font-weight-bold);line-height:1;opacity:.5;padding:1rem;transition:opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.close:hover{opacity:.7}.close:focus,.theme-code-block-highlighted-line .codeLineNumber_Tfdd:before{opacity:.8}.dropdown{display:inline-flex;font-weight:var(--ifm-dropdown-font-weight);position:relative;vertical-align:top}.dropdown--hoverable:hover .dropdown__menu,.dropdown--show .dropdown__menu{opacity:1;pointer-events:all;transform:translateY(-1px);visibility:visible}#nprogress,.dropdown__menu,.navbar__item.dropdown .navbar__link:not([href]){pointer-events:none}.dropdown--right .dropdown__menu{left:inherit;right:0}.dropdown--nocaret .navbar__link:after{content:none!important}.dropdown__menu{background-color:var(--ifm-dropdown-background-color);border-radius:var(--ifm-global-radius);box-shadow:var(--ifm-global-shadow-md);left:0;max-height:80vh;min-width:10rem;opacity:0;overflow-y:auto;padding:.5rem;position:absolute;top:calc(100% - var(--ifm-navbar-item-padding-vertical) + .3rem);transform:translateY(-.625rem);transition-duration:var(--ifm-transition-fast);transition-property:opacity,transform,visibility;transition-timing-function:var(--ifm-transition-timing-default);visibility:hidden;z-index:var(--ifm-z-index-dropdown)}.menu__caret,.menu__link,.menu__list-item-collapsible{border-radius:.25rem;transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.dropdown__link{border-radius:.25rem;color:var(--ifm-dropdown-link-color);display:block;font-size:.875rem;margin-top:.2rem;padding:.25rem .5rem;white-space:nowrap}.dropdown__link--active,.dropdown__link:hover{background-color:var(--ifm-dropdown-hover-background-color);color:var(--ifm-dropdown-link-color);text-decoration:none}.dropdown__link--active,.dropdown__link--active:hover{--ifm-dropdown-link-color:var(--ifm-link-color)}.dropdown>.navbar__link:after{border-color:currentcolor transparent;border-style:solid;border-width:.4em .4em 0;content:"";margin-left:.3em;position:relative;top:2px;transform:translateY(-50%)}.footer{background-color:var(--ifm-footer-background-color);color:var(--ifm-footer-color);padding:var(--ifm-footer-padding-vertical) var(--ifm-footer-padding-horizontal)}.footer--dark{--ifm-footer-background-color:#303846;--ifm-footer-color:var(--ifm-footer-link-color);--ifm-footer-link-color:var(--ifm-color-secondary);--ifm-footer-title-color:var(--ifm-color-white)}.footer__links{margin-bottom:1rem}.footer__link-item{color:var(--ifm-footer-link-color);line-height:2}.footer__link-item:hover{color:var(--ifm-footer-link-hover-color)}.footer__link-separator{margin:0 var(--ifm-footer-link-horizontal-spacing)}.footer__logo{margin-top:1rem;max-width:var(--ifm-footer-logo-max-width)}.footer__title{color:var(--ifm-footer-title-color);font:700 var(--ifm-h4-font-size)/var(--ifm-heading-line-height) var(--ifm-font-family-base);margin-bottom:var(--ifm-heading-margin-bottom)}.menu,.navbar__link{font-weight:var(--ifm-font-weight-semibold)}.docItemContainer_Djhp article>:first-child,.docItemContainer_Djhp header+*,.footer__item{margin-top:0}.admonitionContent_BuS1>:last-child,.collapsibleContent_i85q p:last-child,.details_lb9f>summary>p:last-child,.footer__items{margin-bottom:0}.codeBlockStandalone_MEMb,[type=checkbox]{padding:0}.hero{align-items:center;background-color:var(--ifm-hero-background-color);color:var(--ifm-hero-text-color);display:flex;padding:4rem 2rem}.hero--primary{--ifm-hero-background-color:var(--ifm-color-primary);--ifm-hero-text-color:var(--ifm-font-color-base-inverse)}.hero--dark{--ifm-hero-background-color:#303846;--ifm-hero-text-color:var(--ifm-color-white)}.hero__title{font-size:3rem}.hero__subtitle{font-size:1.5rem}.menu__list{margin:0;padding-left:0}.menu__caret,.menu__link{padding:var(--ifm-menu-link-padding-vertical) var(--ifm-menu-link-padding-horizontal)}.menu__list .menu__list{flex:0 0 100%;margin-top:.25rem;padding-left:var(--ifm-menu-link-padding-horizontal)}.menu__list-item:not(:first-child){margin-top:.25rem}.menu__list-item--collapsed .menu__list{height:0;overflow:hidden}.details_lb9f[data-collapsed=false].isBrowser_bmU9>summary:before,.details_lb9f[open]:not(.isBrowser_bmU9)>summary:before,.menu__list-item--collapsed .menu__caret:before,.menu__list-item--collapsed .menu__link--sublist:after{transform:rotate(90deg)}.menu__list-item-collapsible{display:flex;flex-wrap:wrap;position:relative}.menu__caret:hover,.menu__link:hover,.menu__list-item-collapsible--active,.menu__list-item-collapsible:hover{background:var(--ifm-menu-color-background-hover)}.menu__list-item-collapsible .menu__link--active,.menu__list-item-collapsible .menu__link:hover{background:none!important}.menu__caret,.menu__link{align-items:center;display:flex}.menu__link{color:var(--ifm-menu-color);flex:1;line-height:1.25}.menu__link:hover{color:var(--ifm-menu-color);text-decoration:none}.menu__caret:before,.menu__link--sublist-caret:after{content:"";height:1.25rem;transform:rotate(180deg);transition:transform var(--ifm-transition-fast) linear;width:1.25rem;filter:var(--ifm-menu-link-sublist-icon-filter)}.menu__link--sublist-caret:after{background:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem;margin-left:auto;min-width:1.25rem}.menu__link--active,.menu__link--active:hover{color:var(--ifm-menu-color-active)}.navbar__brand,.navbar__link{color:var(--ifm-navbar-link-color)}.menu__link--active:not(.menu__link--sublist){background-color:var(--ifm-menu-color-background-active)}.menu__caret:before{background:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem}.navbar--dark,html[data-theme=dark]{--ifm-menu-link-sublist-icon-filter:invert(100%) sepia(94%) saturate(17%) hue-rotate(223deg) brightness(104%) contrast(98%)}.navbar{background-color:var(--ifm-navbar-background-color);box-shadow:var(--ifm-navbar-shadow);height:var(--ifm-navbar-height);padding:var(--ifm-navbar-padding-vertical) var(--ifm-navbar-padding-horizontal)}.landing-two-block-container,.navbar,.navbar>.container,.navbar>.container-fluid{display:flex}.navbar--fixed-top{position:sticky;top:0;z-index:var(--ifm-z-index-fixed)}.navbar-sidebar,.navbar-sidebar__backdrop{bottom:0;opacity:0;position:fixed;transition-duration:var(--ifm-transition-fast);transition-timing-function:ease-in-out;left:0;top:0;visibility:hidden}.navbar__inner{display:flex;flex-wrap:wrap;justify-content:space-between;width:100%}.navbar__brand{align-items:center;display:flex;margin-right:1rem;min-width:0}.navbar__brand:hover{color:var(--ifm-navbar-link-hover-color);text-decoration:none}.announcementBarContent_xLdY,.navbar__title{flex:1 1 auto}.navbar__toggle{display:none;margin-right:.5rem}.navbar__logo{flex:0 0 auto;height:2rem;margin-right:.5rem}.navbar__items{align-items:center;display:flex;flex:1;min-width:0}.navbar__items--center{flex:0 0 auto}.highlights-item>h2,.highlights-item>p,.navbar__items--center .navbar__brand{margin:0}.navbar__items--center+.navbar__items--right{flex:1}.navbar__items--right{flex:0 0 auto;justify-content:flex-end}.navbar__items--right>:last-child{padding-right:0}.navbar__item{display:inline-block;padding:var(--ifm-navbar-item-padding-vertical) var(--ifm-navbar-item-padding-horizontal)}.navbar__link--active,.navbar__link:hover{color:var(--ifm-navbar-link-hover-color);text-decoration:none}.navbar--dark,.navbar--primary{--ifm-menu-color:var(--ifm-color-gray-300);--ifm-navbar-link-color:var(--ifm-color-gray-100);--ifm-navbar-search-input-background-color:hsla(0,0%,100%,.1);--ifm-navbar-search-input-placeholder-color:hsla(0,0%,100%,.5);color:var(--ifm-color-white)}.navbar--dark{--ifm-navbar-background-color:#242526;--ifm-menu-color-background-active:hsla(0,0%,100%,.05);--ifm-navbar-search-input-color:var(--ifm-color-white)}.navbar--primary{--ifm-navbar-background-color:var(--ifm-color-primary);--ifm-navbar-link-hover-color:var(--ifm-color-white);--ifm-menu-color-active:var(--ifm-color-white);--ifm-navbar-search-input-color:var(--ifm-color-emphasis-500)}.navbar__search-input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:var(--ifm-navbar-search-input-background-color) var(--ifm-navbar-search-input-icon) no-repeat .75rem center/1rem 1rem;border:none;border-radius:2rem;color:var(--ifm-navbar-search-input-color);cursor:text;display:inline-block;font-size:.9rem;height:2rem;padding:0 .5rem 0 2.25rem;width:12.5rem}.navbar__search-input::-moz-placeholder{color:var(--ifm-navbar-search-input-placeholder-color)}.navbar__search-input::placeholder{color:var(--ifm-navbar-search-input-placeholder-color)}.navbar-sidebar{background-color:var(--ifm-navbar-background-color);box-shadow:var(--ifm-global-shadow-md);transform:translate3d(-100%,0,0);transition-property:opacity,visibility,transform;width:var(--ifm-navbar-sidebar-width)}.navbar-sidebar--show .navbar-sidebar,.navbar-sidebar__items{transform:translateZ(0)}.navbar-sidebar--show .navbar-sidebar,.navbar-sidebar--show .navbar-sidebar__backdrop{opacity:1;visibility:visible}.navbar-sidebar__backdrop{background-color:rgba(0,0,0,.6);right:0;transition-property:opacity,visibility}.navbar-sidebar__brand{align-items:center;box-shadow:var(--ifm-navbar-shadow);display:flex;flex:1;height:var(--ifm-navbar-height);padding:var(--ifm-navbar-padding-vertical) var(--ifm-navbar-padding-horizontal)}.navbar-sidebar__items{display:flex;height:calc(100% - var(--ifm-navbar-height));transition:transform var(--ifm-transition-fast) ease-in-out}.navbar-sidebar__items--show-secondary{transform:translate3d(calc((var(--ifm-navbar-sidebar-width))*-1),0,0)}.navbar-sidebar__item{flex-shrink:0;padding:.5rem;width:calc(var(--ifm-navbar-sidebar-width))}.navbar-sidebar__back{background:var(--ifm-menu-color-background-active);font-size:15px;font-weight:var(--ifm-button-font-weight);margin:0 0 .2rem -.5rem;padding:.6rem 1.5rem;position:relative;text-align:left;top:-.5rem;width:calc(100% + 1rem)}.navbar-sidebar__close{display:flex;margin-left:auto}.pagination{-moz-column-gap:var(--ifm-pagination-page-spacing);column-gap:var(--ifm-pagination-page-spacing);display:flex;font-size:var(--ifm-pagination-font-size);padding-left:0}.pagination--sm{--ifm-pagination-font-size:0.8rem;--ifm-pagination-padding-horizontal:0.8rem;--ifm-pagination-padding-vertical:0.2rem}.pagination--lg{--ifm-pagination-font-size:1.2rem;--ifm-pagination-padding-horizontal:1.2rem;--ifm-pagination-padding-vertical:0.3rem}.pagination__item{display:inline-flex}.pagination__item>span{padding:var(--ifm-pagination-padding-vertical)}.pagination__item--active .pagination__link{color:var(--ifm-pagination-color-active)}.pagination__item--active .pagination__link,.pagination__item:not(.pagination__item--active):hover .pagination__link{background:var(--ifm-pagination-item-active-background)}.pagination__item--disabled,.pagination__item[disabled]{opacity:.25;pointer-events:none}.pagination__link{border-radius:var(--ifm-pagination-border-radius);color:var(--ifm-font-color-base);display:inline-block;padding:var(--ifm-pagination-padding-vertical) var(--ifm-pagination-padding-horizontal);transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.pagination__link:hover{text-decoration:none}.pagination-nav{grid-gap:var(--ifm-spacing-horizontal);display:grid;gap:var(--ifm-spacing-horizontal);grid-template-columns:repeat(2,1fr)}.pagination-nav__link{border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-pagination-nav-border-radius);display:block;height:100%;line-height:var(--ifm-heading-line-height);padding:var(--ifm-global-spacing);transition:border-color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.pagination-nav__link:hover{border-color:var(--ifm-pagination-nav-color-hover);text-decoration:none}.pagination-nav__link--next{grid-column:2/3;text-align:right}.pagination-nav__label{font-size:var(--ifm-h4-font-size);font-weight:var(--ifm-heading-font-weight);word-break:break-word}.pagination-nav__link--prev .pagination-nav__label:before{content:"« "}.pagination-nav__link--next .pagination-nav__label:after{content:" »"}.pagination-nav__sublabel{color:var(--ifm-color-content-secondary);font-size:var(--ifm-h5-font-size);font-weight:var(--ifm-font-weight-semibold);margin-bottom:.25rem}.pills__item,.tabs{font-weight:var(--ifm-font-weight-bold)}.pills{display:flex;gap:var(--ifm-pills-spacing);padding-left:0}.pills__item{border-radius:.5rem;cursor:pointer;display:inline-block;padding:.25rem 1rem;transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.tabs,:not(.containsTaskList_mC6p>li)>.containsTaskList_mC6p{padding-left:0}.pills__item--active{color:var(--ifm-pills-color-active)}.pills__item--active,.pills__item:not(.pills__item--active):hover{background:var(--ifm-pills-color-background-active)}.pills--block{justify-content:stretch}.pills--block .pills__item{flex-grow:1;text-align:center}.tabs{color:var(--ifm-tabs-color);display:flex;margin-bottom:0;overflow-x:auto}.tabs__item{border-bottom:3px solid transparent;border-radius:var(--ifm-global-radius);cursor:pointer;display:inline-flex;padding:var(--ifm-tabs-padding-vertical) var(--ifm-tabs-padding-horizontal);transition:background-color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.tabs__item--active{border-bottom-color:var(--ifm-tabs-color-active-border);border-bottom-left-radius:0;border-bottom-right-radius:0;color:var(--ifm-tabs-color-active)}.tabs__item:hover{background-color:var(--ifm-hover-overlay)}.tabs--block{justify-content:stretch}.tabs--block .tabs__item{flex-grow:1;justify-content:center}html[data-theme=dark]{--ifm-color-scheme:dark;--ifm-color-emphasis-0:var(--ifm-color-gray-1000);--ifm-color-emphasis-100:var(--ifm-color-gray-900);--ifm-color-emphasis-200:var(--ifm-color-gray-800);--ifm-color-emphasis-300:var(--ifm-color-gray-700);--ifm-color-emphasis-400:var(--ifm-color-gray-600);--ifm-color-emphasis-600:var(--ifm-color-gray-400);--ifm-color-emphasis-700:var(--ifm-color-gray-300);--ifm-color-emphasis-800:var(--ifm-color-gray-200);--ifm-color-emphasis-900:var(--ifm-color-gray-100);--ifm-color-emphasis-1000:var(--ifm-color-gray-0);--ifm-background-color:#1b1b1d;--ifm-background-surface-color:#242526;--ifm-hover-overlay:hsla(0,0%,100%,.05);--ifm-color-content:#e3e3e3;--ifm-color-content-secondary:#fff;--ifm-breadcrumb-separator-filter:invert(64%) sepia(11%) saturate(0%) hue-rotate(149deg) brightness(99%) contrast(95%);--ifm-code-background:hsla(0,0%,100%,.1);--ifm-scrollbar-track-background-color:#444;--ifm-scrollbar-thumb-background-color:#686868;--ifm-scrollbar-thumb-hover-background-color:#7a7a7a;--ifm-table-stripe-background:hsla(0,0%,100%,.07);--ifm-toc-border-color:var(--ifm-color-emphasis-200);--ifm-color-primary-contrast-background:#102445;--ifm-color-primary-contrast-foreground:#ebf2fc;--ifm-color-secondary-contrast-background:#474748;--ifm-color-secondary-contrast-foreground:#fdfdfe;--ifm-color-success-contrast-background:#003100;--ifm-color-success-contrast-foreground:#e6f6e6;--ifm-color-info-contrast-background:#193c47;--ifm-color-info-contrast-foreground:#eef9fd;--ifm-color-warning-contrast-background:#4d3800;--ifm-color-warning-contrast-foreground:#fff8e6;--ifm-color-danger-contrast-background:#4b1113;--ifm-color-danger-contrast-foreground:#ffebec}:root{--docusaurus-progress-bar-color:var(--ifm-color-primary);--ifm-color-primary-lightest:#03a697;--ifm-color-primary-lighter:#029385;--ifm-color-primary-light:#028d80;--ifm-color-primary:#028074;--ifm-color-primary-dark:#027368;--ifm-color-primary-darker:#026d63;--ifm-color-primary-darkest:#015a51;--ifm-section-alt1-background:#fff;--ifm-section-alt2-background:#f7f7f7;--ifm-navbar-background-color:#028074;--ifm-navbar-link-color:hsla(0,0%,100%,.85);--ifm-navbar-link-hover-color:#fff;--docusaurus-announcement-bar-height:auto;--docusaurus-tag-list-border:var(--ifm-color-emphasis-300);--docusaurus-collapse-button-bg:transparent;--docusaurus-collapse-button-bg-hover:rgba(0,0,0,.1);--doc-sidebar-width:300px;--doc-sidebar-hidden-width:30px}#nprogress .bar{background:var(--docusaurus-progress-bar-color);height:2px;left:0;position:fixed;top:0;width:100%;z-index:1031}#nprogress .peg{box-shadow:0 0 10px var(--docusaurus-progress-bar-color),0 0 5px var(--docusaurus-progress-bar-color);height:100%;opacity:1;position:absolute;right:0;transform:rotate(3deg) translateY(-4px);width:100px}[data-theme=dark]:root{--ifm-section-alt1-background:#242424;--ifm-section-alt2-background:#414141;--docusaurus-collapse-button-bg:hsla(0,0%,100%,.05);--docusaurus-collapse-button-bg-hover:hsla(0,0%,100%,.1)}section{padding:5rem 0}h2{font-weight:600}.btn{border:1px solid var(--ifm-color-primary);border-radius:3px;font-size:14px;font-weight:400;line-height:1.2em;padding:10px;transition:background .3s,color .3s}.btn-full,.btn-outline:hover{background:var(--ifm-color-primary);color:#fff}.btn-full:hover,.btn-outline{background:#fff;color:var(--ifm-color-primary)}.main-wrapper{display:flex;flex-direction:column}#__docusaurus-base-url-issue-banner-container,.landing-two-block-container>img,.themedComponent_mlkZ,[data-theme=dark] .lightToggleIcon_pyhR,[data-theme=light] .darkToggleIcon_wfgR,html[data-announcement-bar-initially-dismissed=true] .announcementBar_mb4j{display:none}.landing-two-block-content{align-items:start;display:flex;flex-direction:column;gap:1.5rem}.home-splash{background:var(--ifm-section-alt1-background);padding:6rem 0}.home-splash-container{align-items:center;display:flex;flex-direction:column;text-align:center}.home-splash-container>h2{color:var(--ifm-color-primary);font-size:2rem;font-weight:400;margin:0 0 2rem;max-width:40rem}.jumbo,.learnhow{background:var(--ifm-section-alt2-background)}.featurelist,.highlights{background:var(--ifm-section-alt1-background)}.highlights-container{-moz-column-gap:3rem;column-gap:3rem;display:flex;flex-direction:column;row-gap:5rem}.highlights-item{align-items:center;display:flex;flex-basis:100%;flex-direction:column;flex-grow:1;flex-shrink:0;gap:1.5rem;max-width:30rem;text-align:center}.highlights-item>img{max-width:30%}.opensource{background:var(--ifm-section-alt3-background);color:#fff}.featurelist-container{display:flex;flex-direction:column;gap:3rem;justify-content:space-around}.featurelist-title{color:var(--ifm-color-primary);flex-basis:100%;text-align:center}.showcase{background:var(--ifm-section-alt1-background);text-align:center}.showcase-container{align-items:center;display:flex;flex-direction:column;gap:2rem}.showcase-logos{align-items:center;display:flex;flex-direction:row;gap:30px;justify-content:center}.showcase-logos>a,.users-showcase-logos>a{background:#fff;padding:10px}.showcase-logos>a>img{max-height:110px;width:110px}.users-showcase{display:flex;flex-grow:1}.help-container,.users-showcase-container{flex-direction:column}.users-showcase-container,.users-showcase-logos{align-items:center;display:flex;justify-content:center}.users-showcase-logos{flex-direction:row;gap:20px}.users-showcase-logos>a>img{max-height:128px;width:128px}.help-container{display:flex;gap:40px}.help-three-col,.help-two-col{display:flex;flex-direction:column;gap:30px}.help-two-col>p{flex-basis:50%;max-width:none}.help-three-col>div{flex-basis:33.33%}body:not(.navigation-with-keyboard) :not(input):focus{outline:0}.skipToContent_fXgn{background-color:var(--ifm-background-surface-color);color:var(--ifm-color-emphasis-900);left:100%;padding:calc(var(--ifm-global-spacing)/2) var(--ifm-global-spacing);position:fixed;top:1rem;z-index:calc(var(--ifm-z-index-fixed) + 1)}.skipToContent_fXgn:focus{box-shadow:var(--ifm-global-shadow-md);left:1rem}.closeButton_CVFx{line-height:0;padding:0}.content_knG7{font-size:85%;padding:5px 0;text-align:center}.content_knG7 a{color:inherit;text-decoration:underline}.announcementBar_mb4j{align-items:center;background-color:var(--ifm-color-white);border-bottom:1px solid var(--ifm-color-emphasis-100);color:var(--ifm-color-black);display:flex;height:var(--docusaurus-announcement-bar-height)}.announcementBarPlaceholder_vyr4{flex:0 0 10px}.announcementBarClose_gvF7{align-self:stretch;flex:0 0 30px}.toggle_vylO{height:2rem;width:2rem}.toggleButton_gllP{align-items:center;border-radius:50%;display:flex;height:100%;justify-content:center;transition:background var(--ifm-transition-fast);width:100%}.toggleButton_gllP:hover{background:var(--ifm-color-emphasis-200)}.toggleButtonDisabled_aARS{cursor:not-allowed}.darkNavbarColorModeToggle_X3D1:hover{background:var(--ifm-color-gray-800)}[data-theme=dark] .themedComponent--dark_xIcU,[data-theme=light] .themedComponent--light_NVdE,html:not([data-theme]) .themedComponent--light_NVdE{display:initial}.iconExternalLink_nPIU{margin-left:.3rem}.dropdownNavbarItemMobile_S0Fm{cursor:pointer}.iconLanguage_nlXk{margin-right:5px;vertical-align:text-bottom}@supports selector(:has(*)){.navbarSearchContainer_Bca1:not(:has(>*)){display:none}}.navbarHideable_m1mJ{transition:transform var(--ifm-transition-fast) ease}.navbarHidden_jGov{transform:translate3d(0,calc(-100% - 2px),0)}.errorBoundaryError_a6uf{color:red;white-space:pre-wrap}.errorBoundaryFallback_VBag{color:red;padding:.55rem}.footerLogoLink_BH7S{opacity:.5;transition:opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.footerLogoLink_BH7S:hover,.hash-link:focus,:hover>.hash-link{opacity:1}.anchorWithStickyNavbar_LWe7{scroll-margin-top:calc(var(--ifm-navbar-height) + .5rem)}.anchorWithHideOnScrollNavbar_WYt5{scroll-margin-top:.5rem}.hash-link{opacity:0;padding-left:.5rem;transition:opacity var(--ifm-transition-fast);-webkit-user-select:none;-moz-user-select:none;user-select:none}.hash-link:before{content:"#"}.mainWrapper_z2l0{display:flex;flex:1 0 auto;flex-direction:column}.docusaurus-mt-lg{margin-top:3rem}#__docusaurus{display:flex;flex-direction:column;min-height:100%}.iconEdit_Z9Sw{margin-right:.3em;vertical-align:sub}.tag_zVej{border:1px solid var(--docusaurus-tag-list-border);transition:border var(--ifm-transition-fast)}.tag_zVej:hover{--docusaurus-tag-list-border:var(--ifm-link-color);text-decoration:none}.tagRegular_sFm0{border-radius:var(--ifm-global-radius);font-size:90%;padding:.2rem .5rem .3rem}.tagWithCount_h2kH{align-items:center;border-left:0;display:flex;padding:0 .5rem 0 1rem;position:relative}.tagWithCount_h2kH:after,.tagWithCount_h2kH:before{border:1px solid var(--docusaurus-tag-list-border);content:"";position:absolute;top:50%;transition:inherit}.tagWithCount_h2kH:before{border-bottom:0;border-right:0;height:1.18rem;right:100%;transform:translate(50%,-50%) rotate(-45deg);width:1.18rem}.tagWithCount_h2kH:after{border-radius:50%;height:.5rem;left:0;transform:translateY(-50%);width:.5rem}.tagWithCount_h2kH span{background:var(--ifm-color-secondary);border-radius:var(--ifm-global-radius);color:var(--ifm-color-black);font-size:.7rem;line-height:1.2;margin-left:.3rem;padding:.1rem .4rem}.tags_jXut{display:inline}.tag_QGVx{display:inline-block;margin:0 .4rem .5rem 0}.lastUpdated_vwxv{font-size:smaller;font-style:italic;margin-top:.2rem}.tocCollapsibleButton_TO0P{align-items:center;display:flex;font-size:inherit;justify-content:space-between;padding:.4rem .8rem;width:100%}.tocCollapsibleButton_TO0P:after{background:var(--ifm-menu-link-sublist-icon) 50% 50%/2rem 2rem no-repeat;content:"";filter:var(--ifm-menu-link-sublist-icon-filter);height:1.25rem;transform:rotate(180deg);transition:transform var(--ifm-transition-fast);width:1.25rem}.tocCollapsibleButtonExpanded_MG3E:after,.tocCollapsibleExpanded_sAul{transform:none}.tocCollapsible_ETCw{background-color:var(--ifm-menu-color-background-active);border-radius:var(--ifm-global-radius);margin:1rem 0}.buttonGroup__atx button,.codeBlockContainer_Ckt0{background:var(--prism-background-color);color:var(--prism-color)}.tocCollapsibleContent_vkbj>ul{border-left:none;border-top:1px solid var(--ifm-color-emphasis-300);font-size:15px;padding:.2rem 0}.tocCollapsibleContent_vkbj ul li{margin:.4rem .8rem}.tocCollapsibleContent_vkbj a{display:block}.tableOfContents_bqdL{max-height:calc(100vh - var(--ifm-navbar-height) - 2rem);overflow-y:auto;position:sticky;top:calc(var(--ifm-navbar-height) + 1rem)}.codeBlockContainer_Ckt0{border-radius:var(--ifm-code-border-radius);box-shadow:var(--ifm-global-shadow-lw);margin-bottom:var(--ifm-leading)}.codeBlockContent_biex{border-radius:inherit;direction:ltr;position:relative}.codeBlockTitle_Ktv7{border-bottom:1px solid var(--ifm-color-emphasis-300);border-top-left-radius:inherit;border-top-right-radius:inherit;font-size:var(--ifm-code-font-size);font-weight:500;padding:.75rem var(--ifm-pre-padding)}.codeBlock_bY9V{--ifm-pre-background:var(--prism-background-color);margin:0;padding:0}.codeBlockTitle_Ktv7+.codeBlockContent_biex .codeBlock_bY9V{border-top-left-radius:0;border-top-right-radius:0}.codeBlockLines_e6Vv{float:left;font:inherit;min-width:100%;padding:var(--ifm-pre-padding)}.codeBlockLinesWithNumbering_o6Pm{display:table;padding:var(--ifm-pre-padding) 0}.buttonGroup__atx{-moz-column-gap:.2rem;column-gap:.2rem;display:flex;position:absolute;right:calc(var(--ifm-pre-padding)/2);top:calc(var(--ifm-pre-padding)/2)}.buttonGroup__atx button{align-items:center;border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-global-radius);display:flex;line-height:0;opacity:0;padding:.4rem;transition:opacity var(--ifm-transition-fast) ease-in-out}.buttonGroup__atx button:focus-visible,.buttonGroup__atx button:hover{opacity:1!important}.theme-code-block:hover .buttonGroup__atx button{opacity:.4}:where(:root){--docusaurus-highlighted-code-line-bg:#484d5b}:where([data-theme=dark]){--docusaurus-highlighted-code-line-bg:#646464}.theme-code-block-highlighted-line{background-color:var(--docusaurus-highlighted-code-line-bg);display:block;margin:0 calc(var(--ifm-pre-padding)*-1);padding:0 var(--ifm-pre-padding)}.codeLine_lJS_{counter-increment:a;display:table-row}.codeLineNumber_Tfdd{background:var(--ifm-pre-background);display:table-cell;left:0;overflow-wrap:normal;padding:0 var(--ifm-pre-padding);position:sticky;text-align:right;width:1%}.codeLineNumber_Tfdd:before{content:counter(a);opacity:.4}.codeLineContent_feaV{padding-right:var(--ifm-pre-padding)}.theme-code-block:hover .copyButtonCopied_obH4{opacity:1!important}.copyButtonIcons_eSgA{height:1.125rem;position:relative;width:1.125rem}.copyButtonIcon_y97N,.copyButtonSuccessIcon_LjdS{fill:currentColor;height:inherit;left:0;opacity:inherit;position:absolute;top:0;transition:all var(--ifm-transition-fast) ease;width:inherit}.copyButtonSuccessIcon_LjdS{color:#00d600;left:50%;opacity:0;top:50%;transform:translate(-50%,-50%) scale(.33)}.copyButtonCopied_obH4 .copyButtonIcon_y97N{opacity:0;transform:scale(.33)}.copyButtonCopied_obH4 .copyButtonSuccessIcon_LjdS{opacity:1;transform:translate(-50%,-50%) scale(1);transition-delay:75ms}.wordWrapButtonIcon_Bwma{height:1.2rem;width:1.2rem}.details_lb9f{--docusaurus-details-summary-arrow-size:0.38rem;--docusaurus-details-transition:transform 200ms ease;--docusaurus-details-decoration-color:grey}.details_lb9f>summary{cursor:pointer;padding-left:1rem;position:relative}.details_lb9f>summary::-webkit-details-marker{display:none}.details_lb9f>summary:before{border-color:transparent transparent transparent var(--docusaurus-details-decoration-color);border-style:solid;border-width:var(--docusaurus-details-summary-arrow-size);content:"";left:0;position:absolute;top:.45rem;transform:rotate(0);transform-origin:calc(var(--docusaurus-details-summary-arrow-size)/2) 50%;transition:var(--docusaurus-details-transition)}.collapsibleContent_i85q{border-top:1px solid var(--docusaurus-details-decoration-color);margin-top:1rem;padding-top:1rem}.details_b_Ee{--docusaurus-details-decoration-color:var(--ifm-alert-border-color);--docusaurus-details-transition:transform var(--ifm-transition-fast) ease;border:1px solid var(--ifm-alert-border-color);margin:0 0 var(--ifm-spacing-vertical)}.img_ev3q{height:auto}.admonition_xJq3{margin-bottom:1em}.admonitionHeading_Gvgb{font:var(--ifm-heading-font-weight) var(--ifm-h5-font-size)/var(--ifm-heading-line-height) var(--ifm-heading-font-family)}.admonitionHeading_Gvgb:not(:last-child){margin-bottom:.3rem}.admonitionHeading_Gvgb code{text-transform:none}.admonitionIcon_Rf37{display:inline-block;margin-right:.4em;vertical-align:middle}.admonitionIcon_Rf37 svg{fill:var(--ifm-alert-foreground-color);display:inline-block;height:1.6em;width:1.6em}.breadcrumbHomeIcon_YNFT{height:1.1rem;position:relative;top:1px;vertical-align:top;width:1.1rem}.breadcrumbsContainer_Z_bl{--ifm-breadcrumb-size-multiplier:0.8;margin-bottom:.8rem}.backToTopButton_sjWU{background-color:var(--ifm-color-emphasis-200);border-radius:50%;bottom:1.3rem;box-shadow:var(--ifm-global-shadow-lw);height:3rem;opacity:0;position:fixed;right:1.3rem;transform:scale(0);transition:all var(--ifm-transition-fast) var(--ifm-transition-timing-default);visibility:hidden;width:3rem;z-index:calc(var(--ifm-z-index-fixed) - 1)}.backToTopButton_sjWU:after{background-color:var(--ifm-color-emphasis-1000);content:" ";display:inline-block;height:100%;-webkit-mask:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem no-repeat;mask:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem no-repeat;width:100%}.backToTopButtonShow_xfvO{opacity:1;transform:scale(1);visibility:visible}.collapseSidebarButton_PEFL{display:none;margin:0}.docSidebarContainer_YfHR,.sidebarLogo_isFc{display:none}.docMainContainer_TBSr,.docRoot_UBD9{display:flex;width:100%}.docsWrapper_hBAB{display:flex;flex:1 0 auto}@media only screen and (min-width:736px){.landing-two-block-container{align-items:center;flex-direction:row;justify-content:space-around}.landing-two-block-container>img{display:block;margin-right:40px;max-width:500px;width:50%}.highlights-container{flex-direction:row;flex-wrap:wrap;justify-content:center}.highlights-item{flex-basis:40%}.featurelist-container{flex-direction:row;flex-wrap:wrap}.help-three-col,.help-two-col{flex-direction:row}}@media (min-width:997px){.collapseSidebarButton_PEFL,.expandButton_TmdG{background-color:var(--docusaurus-collapse-button-bg)}:root{--docusaurus-announcement-bar-height:30px}.announcementBarClose_gvF7,.announcementBarPlaceholder_vyr4{flex-basis:50px}.navbarSearchContainer_Bca1{padding:var(--ifm-navbar-item-padding-vertical) var(--ifm-navbar-item-padding-horizontal)}.lastUpdated_vwxv{text-align:right}.tocMobile_ITEo{display:none}.docItemCol_VOVn{max-width:75%!important}.collapseSidebarButton_PEFL{border:1px solid var(--ifm-toc-border-color);border-radius:0;bottom:0;display:block!important;height:40px;position:sticky}.collapseSidebarButtonIcon_kv0_{margin-top:4px;transform:rotate(180deg)}.expandButtonIcon_i1dp,[dir=rtl] .collapseSidebarButtonIcon_kv0_{transform:rotate(0)}.collapseSidebarButton_PEFL:focus,.collapseSidebarButton_PEFL:hover,.expandButton_TmdG:focus,.expandButton_TmdG:hover{background-color:var(--docusaurus-collapse-button-bg-hover)}.menuHtmlItem_M9Kj{padding:var(--ifm-menu-link-padding-vertical) var(--ifm-menu-link-padding-horizontal)}.menu_SIkG{flex-grow:1;padding:.5rem}@supports (scrollbar-gutter:stable){.menu_SIkG{padding:.5rem 0 .5rem .5rem;scrollbar-gutter:stable}}.menuWithAnnouncementBar_GW3s{margin-bottom:var(--docusaurus-announcement-bar-height)}.sidebar_njMd{display:flex;flex-direction:column;height:100%;padding-top:var(--ifm-navbar-height);width:var(--doc-sidebar-width)}.sidebarWithHideableNavbar_wUlq{padding-top:0}.sidebarHidden_VK0M{opacity:0;visibility:hidden}.sidebarLogo_isFc{align-items:center;color:inherit!important;display:flex!important;margin:0 var(--ifm-navbar-padding-horizontal);max-height:var(--ifm-navbar-height);min-height:var(--ifm-navbar-height);text-decoration:none!important}.sidebarLogo_isFc img{height:2rem;margin-right:.5rem}.expandButton_TmdG{align-items:center;display:flex;height:100%;justify-content:center;position:absolute;right:0;top:0;transition:background-color var(--ifm-transition-fast) ease;width:100%}[dir=rtl] .expandButtonIcon_i1dp{transform:rotate(180deg)}.docSidebarContainer_YfHR{border-right:1px solid var(--ifm-toc-border-color);-webkit-clip-path:inset(0);clip-path:inset(0);display:block;margin-top:calc(var(--ifm-navbar-height)*-1);transition:width var(--ifm-transition-fast) ease;width:var(--doc-sidebar-width);will-change:width}.docSidebarContainerHidden_DPk8{cursor:pointer;width:var(--doc-sidebar-hidden-width)}.sidebarViewport_aRkj{height:100%;max-height:100vh;position:sticky;top:0}.docMainContainer_TBSr{flex-grow:1;max-width:calc(100% - var(--doc-sidebar-width))}.docMainContainerEnhanced_lQrH{max-width:calc(100% - var(--doc-sidebar-hidden-width))}.docItemWrapperEnhanced_JWYK{max-width:calc(var(--ifm-container-width) + var(--doc-sidebar-width))!important}}@media (min-width:1440px){.container{max-width:var(--ifm-container-width-xl)}}@media only screen and (min-width:1500px){section>.container{margin:auto;max-width:1400px}}@media (max-width:996px){.col{--ifm-col-width:100%;flex-basis:var(--ifm-col-width);margin-left:0}.footer{--ifm-footer-padding-horizontal:0}.colorModeToggle_DEke,.footer__link-separator,.navbar__item,.tableOfContents_bqdL{display:none}.footer__col{margin-bottom:calc(var(--ifm-spacing-vertical)*3)}.footer__link-item{display:block}.hero{padding-left:0;padding-right:0}.navbar>.container,.navbar>.container-fluid{padding:0}.navbar__toggle{display:inherit}.navbar__search-input{width:9rem}.pills--block,.tabs--block{flex-direction:column}.navbarSearchContainer_Bca1{position:absolute;right:var(--ifm-navbar-padding-horizontal)}.docItemContainer_F8PC{padding:0 .3rem}}@media (max-width:576px){.markdown h1:first-child{--ifm-h1-font-size:2rem}.markdown>h2{--ifm-h2-font-size:1.5rem}.markdown>h3{--ifm-h3-font-size:1.25rem}}@media (hover:hover){.backToTopButton_sjWU:hover{background-color:var(--ifm-color-emphasis-300)}}@media (pointer:fine){.thin-scrollbar{scrollbar-width:thin}.thin-scrollbar::-webkit-scrollbar{height:var(--ifm-scrollbar-size);width:var(--ifm-scrollbar-size)}.thin-scrollbar::-webkit-scrollbar-track{background:var(--ifm-scrollbar-track-background-color);border-radius:10px}.thin-scrollbar::-webkit-scrollbar-thumb{background:var(--ifm-scrollbar-thumb-background-color);border-radius:10px}.thin-scrollbar::-webkit-scrollbar-thumb:hover{background:var(--ifm-scrollbar-thumb-hover-background-color)}}@media (prefers-reduced-motion:reduce){:root{--ifm-transition-fast:0ms;--ifm-transition-slow:0ms}}@media print{.announcementBar_mb4j,.footer,.menu,.navbar,.pagination-nav,.table-of-contents,.tocMobile_ITEo{display:none}.tabs{page-break-inside:avoid}.codeBlockLines_e6Vv{white-space:pre-wrap}} \ No newline at end of file +.col,.container{padding:0 var(--ifm-spacing-horizontal);width:100%}.markdown>h2,.markdown>h3,.markdown>h4,.markdown>h5,.markdown>h6{margin-bottom:calc(var(--ifm-heading-vertical-rhythm-bottom)*var(--ifm-leading))}.markdown li,body{word-wrap:break-word}body,ol ol,ol ul,ul ol,ul ul{margin:0}pre,table{overflow:auto}blockquote,pre{margin:0 0 var(--ifm-spacing-vertical)}.breadcrumbs__link,.button{transition-timing-function:var(--ifm-transition-timing-default)}.button,code{vertical-align:middle}.button--outline.button--active,.button--outline:active,.button--outline:hover,:root{--ifm-button-color:var(--ifm-font-color-base-inverse)}.menu__link:hover,a{transition:color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.navbar--dark,:root{--ifm-navbar-link-hover-color:var(--ifm-color-primary)}.menu,.navbar-sidebar{overflow-x:hidden}:root,html[data-theme=dark]{--ifm-color-emphasis-500:var(--ifm-color-gray-500)}:root,[data-theme=dark]:root{--ifm-section-alt3-background:grey}.toggleButton_gllP,html{-webkit-tap-highlight-color:transparent}.clean-list,.containsTaskList_mC6p,.details_lb9f>summary,.dropdown__menu,.menu__list{list-style:none}:root{--ifm-color-scheme:light;--ifm-dark-value:10%;--ifm-darker-value:15%;--ifm-darkest-value:30%;--ifm-light-value:15%;--ifm-lighter-value:30%;--ifm-lightest-value:50%;--ifm-contrast-background-value:90%;--ifm-contrast-foreground-value:70%;--ifm-contrast-background-dark-value:70%;--ifm-contrast-foreground-dark-value:90%;--ifm-color-primary:#3578e5;--ifm-color-secondary:#ebedf0;--ifm-color-success:#00a400;--ifm-color-info:#54c7ec;--ifm-color-warning:#ffba00;--ifm-color-danger:#fa383e;--ifm-color-primary-dark:#306cce;--ifm-color-primary-darker:#2d66c3;--ifm-color-primary-darkest:#2554a0;--ifm-color-primary-light:#538ce9;--ifm-color-primary-lighter:#72a1ed;--ifm-color-primary-lightest:#9abcf2;--ifm-color-primary-contrast-background:#ebf2fc;--ifm-color-primary-contrast-foreground:#102445;--ifm-color-secondary-dark:#d4d5d8;--ifm-color-secondary-darker:#c8c9cc;--ifm-color-secondary-darkest:#a4a6a8;--ifm-color-secondary-light:#eef0f2;--ifm-color-secondary-lighter:#f1f2f5;--ifm-color-secondary-lightest:#f5f6f8;--ifm-color-secondary-contrast-background:#fdfdfe;--ifm-color-secondary-contrast-foreground:#474748;--ifm-color-success-dark:#009400;--ifm-color-success-darker:#008b00;--ifm-color-success-darkest:#007300;--ifm-color-success-light:#26b226;--ifm-color-success-lighter:#4dbf4d;--ifm-color-success-lightest:#80d280;--ifm-color-success-contrast-background:#e6f6e6;--ifm-color-success-contrast-foreground:#003100;--ifm-color-info-dark:#4cb3d4;--ifm-color-info-darker:#47a9c9;--ifm-color-info-darkest:#3b8ba5;--ifm-color-info-light:#6ecfef;--ifm-color-info-lighter:#87d8f2;--ifm-color-info-lightest:#aae3f6;--ifm-color-info-contrast-background:#eef9fd;--ifm-color-info-contrast-foreground:#193c47;--ifm-color-warning-dark:#e6a700;--ifm-color-warning-darker:#d99e00;--ifm-color-warning-darkest:#b38200;--ifm-color-warning-light:#ffc426;--ifm-color-warning-lighter:#ffcf4d;--ifm-color-warning-lightest:#ffdd80;--ifm-color-warning-contrast-background:#fff8e6;--ifm-color-warning-contrast-foreground:#4d3800;--ifm-color-danger-dark:#e13238;--ifm-color-danger-darker:#d53035;--ifm-color-danger-darkest:#af272b;--ifm-color-danger-light:#fb565b;--ifm-color-danger-lighter:#fb7478;--ifm-color-danger-lightest:#fd9c9f;--ifm-color-danger-contrast-background:#ffebec;--ifm-color-danger-contrast-foreground:#4b1113;--ifm-color-white:#fff;--ifm-color-black:#000;--ifm-color-gray-0:var(--ifm-color-white);--ifm-color-gray-100:#f5f6f7;--ifm-color-gray-200:#ebedf0;--ifm-color-gray-300:#dadde1;--ifm-color-gray-400:#ccd0d5;--ifm-color-gray-500:#bec3c9;--ifm-color-gray-600:#8d949e;--ifm-color-gray-700:#606770;--ifm-color-gray-800:#444950;--ifm-color-gray-900:#1c1e21;--ifm-color-gray-1000:var(--ifm-color-black);--ifm-color-emphasis-0:var(--ifm-color-gray-0);--ifm-color-emphasis-100:var(--ifm-color-gray-100);--ifm-color-emphasis-200:var(--ifm-color-gray-200);--ifm-color-emphasis-300:var(--ifm-color-gray-300);--ifm-color-emphasis-400:var(--ifm-color-gray-400);--ifm-color-emphasis-600:var(--ifm-color-gray-600);--ifm-color-emphasis-700:var(--ifm-color-gray-700);--ifm-color-emphasis-800:var(--ifm-color-gray-800);--ifm-color-emphasis-900:var(--ifm-color-gray-900);--ifm-color-emphasis-1000:var(--ifm-color-gray-1000);--ifm-color-content:var(--ifm-color-emphasis-900);--ifm-color-content-inverse:var(--ifm-color-emphasis-0);--ifm-color-content-secondary:#525860;--ifm-background-color:transparent;--ifm-background-surface-color:var(--ifm-color-content-inverse);--ifm-global-border-width:1px;--ifm-global-radius:0.4rem;--ifm-hover-overlay:rgba(0,0,0,.05);--ifm-font-color-base:var(--ifm-color-content);--ifm-font-color-base-inverse:var(--ifm-color-content-inverse);--ifm-font-color-secondary:var(--ifm-color-content-secondary);--ifm-font-family-base:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--ifm-font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--ifm-font-size-base:100%;--ifm-font-weight-light:300;--ifm-font-weight-normal:400;--ifm-font-weight-semibold:500;--ifm-font-weight-bold:700;--ifm-font-weight-base:var(--ifm-font-weight-normal);--ifm-line-height-base:1.65;--ifm-global-spacing:1rem;--ifm-spacing-vertical:var(--ifm-global-spacing);--ifm-spacing-horizontal:var(--ifm-global-spacing);--ifm-transition-fast:200ms;--ifm-transition-slow:400ms;--ifm-transition-timing-default:cubic-bezier(0.08,0.52,0.52,1);--ifm-global-shadow-lw:0 1px 2px 0 rgba(0,0,0,.1);--ifm-global-shadow-md:0 5px 40px rgba(0,0,0,.2);--ifm-global-shadow-tl:0 12px 28px 0 rgba(0,0,0,.2),0 2px 4px 0 rgba(0,0,0,.1);--ifm-z-index-dropdown:100;--ifm-z-index-fixed:200;--ifm-z-index-overlay:400;--ifm-container-width:1140px;--ifm-container-width-xl:1320px;--ifm-code-background:#f6f7f8;--ifm-code-border-radius:var(--ifm-global-radius);--ifm-code-font-size:90%;--ifm-code-padding-horizontal:0.1rem;--ifm-code-padding-vertical:0.1rem;--ifm-pre-background:var(--ifm-code-background);--ifm-pre-border-radius:var(--ifm-code-border-radius);--ifm-pre-color:inherit;--ifm-pre-line-height:1.45;--ifm-pre-padding:1rem;--ifm-heading-color:inherit;--ifm-heading-margin-top:0;--ifm-heading-margin-bottom:var(--ifm-spacing-vertical);--ifm-heading-font-family:var(--ifm-font-family-base);--ifm-heading-font-weight:var(--ifm-font-weight-bold);--ifm-heading-line-height:1.25;--ifm-h1-font-size:2rem;--ifm-h2-font-size:1.5rem;--ifm-h3-font-size:1.25rem;--ifm-h4-font-size:1rem;--ifm-h5-font-size:0.875rem;--ifm-h6-font-size:0.85rem;--ifm-image-alignment-padding:1.25rem;--ifm-leading-desktop:1.25;--ifm-leading:calc(var(--ifm-leading-desktop)*1rem);--ifm-list-left-padding:2rem;--ifm-list-margin:1rem;--ifm-list-item-margin:0.25rem;--ifm-list-paragraph-margin:1rem;--ifm-table-cell-padding:0.75rem;--ifm-table-background:transparent;--ifm-table-stripe-background:rgba(0,0,0,.03);--ifm-table-border-width:1px;--ifm-table-border-color:var(--ifm-color-emphasis-300);--ifm-table-head-background:inherit;--ifm-table-head-color:inherit;--ifm-table-head-font-weight:var(--ifm-font-weight-bold);--ifm-table-cell-color:inherit;--ifm-link-color:var(--ifm-color-primary);--ifm-link-decoration:none;--ifm-link-hover-color:var(--ifm-link-color);--ifm-link-hover-decoration:underline;--ifm-paragraph-margin-bottom:var(--ifm-leading);--ifm-blockquote-font-size:var(--ifm-font-size-base);--ifm-blockquote-border-left-width:2px;--ifm-blockquote-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-blockquote-padding-vertical:0;--ifm-blockquote-shadow:none;--ifm-blockquote-color:var(--ifm-color-emphasis-800);--ifm-blockquote-border-color:var(--ifm-color-emphasis-300);--ifm-hr-background-color:var(--ifm-color-emphasis-500);--ifm-hr-height:1px;--ifm-hr-margin-vertical:1.5rem;--ifm-scrollbar-size:7px;--ifm-scrollbar-track-background-color:#f1f1f1;--ifm-scrollbar-thumb-background-color:silver;--ifm-scrollbar-thumb-hover-background-color:#a7a7a7;--ifm-alert-background-color:inherit;--ifm-alert-border-color:inherit;--ifm-alert-border-radius:var(--ifm-global-radius);--ifm-alert-border-width:0px;--ifm-alert-border-left-width:5px;--ifm-alert-color:var(--ifm-font-color-base);--ifm-alert-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-alert-padding-vertical:var(--ifm-spacing-vertical);--ifm-alert-shadow:var(--ifm-global-shadow-lw);--ifm-avatar-intro-margin:1rem;--ifm-avatar-intro-alignment:inherit;--ifm-avatar-photo-size:3rem;--ifm-badge-background-color:inherit;--ifm-badge-border-color:inherit;--ifm-badge-border-radius:var(--ifm-global-radius);--ifm-badge-border-width:var(--ifm-global-border-width);--ifm-badge-color:var(--ifm-color-white);--ifm-badge-padding-horizontal:calc(var(--ifm-spacing-horizontal)*0.5);--ifm-badge-padding-vertical:calc(var(--ifm-spacing-vertical)*0.25);--ifm-breadcrumb-border-radius:1.5rem;--ifm-breadcrumb-spacing:0.5rem;--ifm-breadcrumb-color-active:var(--ifm-color-primary);--ifm-breadcrumb-item-background-active:var(--ifm-hover-overlay);--ifm-breadcrumb-padding-horizontal:0.8rem;--ifm-breadcrumb-padding-vertical:0.4rem;--ifm-breadcrumb-size-multiplier:1;--ifm-breadcrumb-separator:url('data:image/svg+xml;utf8,');--ifm-breadcrumb-separator-filter:none;--ifm-breadcrumb-separator-size:0.5rem;--ifm-breadcrumb-separator-size-multiplier:1.25;--ifm-button-background-color:inherit;--ifm-button-border-color:var(--ifm-button-background-color);--ifm-button-border-width:var(--ifm-global-border-width);--ifm-button-font-weight:var(--ifm-font-weight-bold);--ifm-button-padding-horizontal:1.5rem;--ifm-button-padding-vertical:0.375rem;--ifm-button-size-multiplier:1;--ifm-button-transition-duration:var(--ifm-transition-fast);--ifm-button-border-radius:calc(var(--ifm-global-radius)*var(--ifm-button-size-multiplier));--ifm-button-group-spacing:2px;--ifm-card-background-color:var(--ifm-background-surface-color);--ifm-card-border-radius:calc(var(--ifm-global-radius)*2);--ifm-card-horizontal-spacing:var(--ifm-global-spacing);--ifm-card-vertical-spacing:var(--ifm-global-spacing);--ifm-toc-border-color:var(--ifm-color-emphasis-300);--ifm-toc-link-color:var(--ifm-color-content-secondary);--ifm-toc-padding-vertical:0.5rem;--ifm-toc-padding-horizontal:0.5rem;--ifm-dropdown-background-color:var(--ifm-background-surface-color);--ifm-dropdown-font-weight:var(--ifm-font-weight-semibold);--ifm-dropdown-link-color:var(--ifm-font-color-base);--ifm-dropdown-hover-background-color:var(--ifm-hover-overlay);--ifm-footer-background-color:var(--ifm-color-emphasis-100);--ifm-footer-color:inherit;--ifm-footer-link-color:var(--ifm-color-emphasis-700);--ifm-footer-link-hover-color:var(--ifm-color-primary);--ifm-footer-link-horizontal-spacing:0.5rem;--ifm-footer-padding-horizontal:calc(var(--ifm-spacing-horizontal)*2);--ifm-footer-padding-vertical:calc(var(--ifm-spacing-vertical)*2);--ifm-footer-title-color:inherit;--ifm-footer-logo-max-width:min(30rem,90vw);--ifm-hero-background-color:var(--ifm-background-surface-color);--ifm-hero-text-color:var(--ifm-color-emphasis-800);--ifm-menu-color:var(--ifm-color-emphasis-700);--ifm-menu-color-active:var(--ifm-color-primary);--ifm-menu-color-background-active:var(--ifm-hover-overlay);--ifm-menu-color-background-hover:var(--ifm-hover-overlay);--ifm-menu-link-padding-horizontal:0.75rem;--ifm-menu-link-padding-vertical:0.375rem;--ifm-menu-link-sublist-icon:url('data:image/svg+xml;utf8,');--ifm-menu-link-sublist-icon-filter:none;--ifm-navbar-background-color:var(--ifm-background-surface-color);--ifm-navbar-height:3.75rem;--ifm-navbar-item-padding-horizontal:0.75rem;--ifm-navbar-item-padding-vertical:0.25rem;--ifm-navbar-link-color:var(--ifm-font-color-base);--ifm-navbar-link-active-color:var(--ifm-link-color);--ifm-navbar-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-navbar-padding-vertical:calc(var(--ifm-spacing-vertical)*0.5);--ifm-navbar-shadow:var(--ifm-global-shadow-lw);--ifm-navbar-search-input-background-color:var(--ifm-color-emphasis-200);--ifm-navbar-search-input-color:var(--ifm-color-emphasis-800);--ifm-navbar-search-input-placeholder-color:var(--ifm-color-emphasis-500);--ifm-navbar-search-input-icon:url('data:image/svg+xml;utf8,');--ifm-navbar-sidebar-width:83vw;--ifm-pagination-border-radius:var(--ifm-global-radius);--ifm-pagination-color-active:var(--ifm-color-primary);--ifm-pagination-font-size:1rem;--ifm-pagination-item-active-background:var(--ifm-hover-overlay);--ifm-pagination-page-spacing:0.2em;--ifm-pagination-padding-horizontal:calc(var(--ifm-spacing-horizontal)*1);--ifm-pagination-padding-vertical:calc(var(--ifm-spacing-vertical)*0.25);--ifm-pagination-nav-border-radius:var(--ifm-global-radius);--ifm-pagination-nav-color-hover:var(--ifm-color-primary);--ifm-pills-color-active:var(--ifm-color-primary);--ifm-pills-color-background-active:var(--ifm-hover-overlay);--ifm-pills-spacing:0.125rem;--ifm-tabs-color:var(--ifm-font-color-secondary);--ifm-tabs-color-active:var(--ifm-color-primary);--ifm-tabs-color-active-border:var(--ifm-tabs-color-active);--ifm-tabs-padding-horizontal:1rem;--ifm-tabs-padding-vertical:1rem}.badge--danger,.badge--info,.badge--primary,.badge--secondary,.badge--success,.badge--warning{--ifm-badge-border-color:var(--ifm-badge-background-color)}.button--link,.button--outline{--ifm-button-background-color:transparent}*{box-sizing:border-box}html{-webkit-font-smoothing:antialiased;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;text-size-adjust:100%;background-color:var(--ifm-background-color);color:var(--ifm-font-color-base);color-scheme:var(--ifm-color-scheme);font:var(--ifm-font-size-base)/var(--ifm-line-height-base) var(--ifm-font-family-base);text-rendering:optimizelegibility}iframe{border:0;color-scheme:auto}.container{margin:0 auto;max-width:var(--ifm-container-width)}.container--fluid{max-width:inherit}.row{display:flex;flex-wrap:wrap;margin:0 calc(var(--ifm-spacing-horizontal)*-1)}.margin-bottom--none,.margin-vert--none,.markdown>:last-child{margin-bottom:0!important}.margin-top--none,.margin-vert--none{margin-top:0!important}.row--no-gutters{margin-left:0;margin-right:0}.margin-horiz--none,.margin-right--none{margin-right:0!important}.row--no-gutters>.col{padding-left:0;padding-right:0}.row--align-top{align-items:flex-start}.row--align-bottom{align-items:flex-end}.menuExternalLink_NmtK,.row--align-center{align-items:center}.row--align-stretch{align-items:stretch}.row--align-baseline{align-items:baseline}.col{--ifm-col-width:100%;flex:1 0;margin-left:0;max-width:var(--ifm-col-width)}.padding-bottom--none,.padding-vert--none{padding-bottom:0!important}.padding-top--none,.padding-vert--none{padding-top:0!important}.padding-horiz--none,.padding-left--none{padding-left:0!important}.padding-horiz--none,.padding-right--none{padding-right:0!important}.col[class*=col--]{flex:0 0 var(--ifm-col-width)}.col--1{--ifm-col-width:8.33333%}.col--offset-1{margin-left:8.33333%}.col--2{--ifm-col-width:16.66667%}.col--offset-2{margin-left:16.66667%}.col--3{--ifm-col-width:25%}.col--offset-3{margin-left:25%}.col--4{--ifm-col-width:33.33333%}.col--offset-4{margin-left:33.33333%}.col--5{--ifm-col-width:41.66667%}.col--offset-5{margin-left:41.66667%}.col--6{--ifm-col-width:50%}.col--offset-6{margin-left:50%}.col--7{--ifm-col-width:58.33333%}.col--offset-7{margin-left:58.33333%}.col--8{--ifm-col-width:66.66667%}.col--offset-8{margin-left:66.66667%}.col--9{--ifm-col-width:75%}.col--offset-9{margin-left:75%}.col--10{--ifm-col-width:83.33333%}.col--offset-10{margin-left:83.33333%}.col--11{--ifm-col-width:91.66667%}.col--offset-11{margin-left:91.66667%}.col--12{--ifm-col-width:100%}.col--offset-12{margin-left:100%}.margin-horiz--none,.margin-left--none{margin-left:0!important}.margin--none{margin:0!important}.margin-bottom--xs,.margin-vert--xs{margin-bottom:.25rem!important}.margin-top--xs,.margin-vert--xs{margin-top:.25rem!important}.margin-horiz--xs,.margin-left--xs{margin-left:.25rem!important}.margin-horiz--xs,.margin-right--xs{margin-right:.25rem!important}.margin--xs{margin:.25rem!important}.margin-bottom--sm,.margin-vert--sm{margin-bottom:.5rem!important}.margin-top--sm,.margin-vert--sm{margin-top:.5rem!important}.margin-horiz--sm,.margin-left--sm{margin-left:.5rem!important}.margin-horiz--sm,.margin-right--sm{margin-right:.5rem!important}.margin--sm{margin:.5rem!important}.margin-bottom--md,.margin-vert--md{margin-bottom:1rem!important}.margin-top--md,.margin-vert--md{margin-top:1rem!important}.margin-horiz--md,.margin-left--md{margin-left:1rem!important}.margin-horiz--md,.margin-right--md{margin-right:1rem!important}.margin--md{margin:1rem!important}.margin-bottom--lg,.margin-vert--lg{margin-bottom:2rem!important}.margin-top--lg,.margin-vert--lg{margin-top:2rem!important}.margin-horiz--lg,.margin-left--lg{margin-left:2rem!important}.margin-horiz--lg,.margin-right--lg{margin-right:2rem!important}.margin--lg{margin:2rem!important}.margin-bottom--xl,.margin-vert--xl{margin-bottom:5rem!important}.margin-top--xl,.margin-vert--xl{margin-top:5rem!important}.margin-horiz--xl,.margin-left--xl{margin-left:5rem!important}.margin-horiz--xl,.margin-right--xl{margin-right:5rem!important}.margin--xl{margin:5rem!important}.padding--none{padding:0!important}.padding-bottom--xs,.padding-vert--xs{padding-bottom:.25rem!important}.padding-top--xs,.padding-vert--xs{padding-top:.25rem!important}.padding-horiz--xs,.padding-left--xs{padding-left:.25rem!important}.padding-horiz--xs,.padding-right--xs{padding-right:.25rem!important}.padding--xs{padding:.25rem!important}.padding-bottom--sm,.padding-vert--sm{padding-bottom:.5rem!important}.padding-top--sm,.padding-vert--sm{padding-top:.5rem!important}.padding-horiz--sm,.padding-left--sm{padding-left:.5rem!important}.padding-horiz--sm,.padding-right--sm{padding-right:.5rem!important}.padding--sm{padding:.5rem!important}.padding-bottom--md,.padding-vert--md{padding-bottom:1rem!important}.padding-top--md,.padding-vert--md{padding-top:1rem!important}.padding-horiz--md,.padding-left--md{padding-left:1rem!important}.padding-horiz--md,.padding-right--md{padding-right:1rem!important}.padding--md{padding:1rem!important}.padding-bottom--lg,.padding-vert--lg{padding-bottom:2rem!important}.padding-top--lg,.padding-vert--lg{padding-top:2rem!important}.padding-horiz--lg,.padding-left--lg{padding-left:2rem!important}.padding-horiz--lg,.padding-right--lg{padding-right:2rem!important}.padding--lg{padding:2rem!important}.padding-bottom--xl,.padding-vert--xl{padding-bottom:5rem!important}.padding-top--xl,.padding-vert--xl{padding-top:5rem!important}.padding-horiz--xl,.padding-left--xl{padding-left:5rem!important}.padding-horiz--xl,.padding-right--xl{padding-right:5rem!important}.padding--xl{padding:5rem!important}code{background-color:var(--ifm-code-background);border:.1rem solid rgba(0,0,0,.1);border-radius:var(--ifm-code-border-radius);font-family:var(--ifm-font-family-monospace);font-size:var(--ifm-code-font-size);padding:var(--ifm-code-padding-vertical) var(--ifm-code-padding-horizontal)}a code{color:inherit}pre{background-color:var(--ifm-pre-background);border-radius:var(--ifm-pre-border-radius);color:var(--ifm-pre-color);font:var(--ifm-code-font-size)/var(--ifm-pre-line-height) var(--ifm-font-family-monospace);padding:var(--ifm-pre-padding)}pre code{background-color:transparent;border:none;font-size:100%;line-height:inherit;padding:0}kbd{background-color:var(--ifm-color-emphasis-0);border:1px solid var(--ifm-color-emphasis-400);border-radius:.2rem;box-shadow:inset 0 -1px 0 var(--ifm-color-emphasis-400);color:var(--ifm-color-emphasis-800);font:80% var(--ifm-font-family-monospace);padding:.15rem .3rem}h1,h2,h3,h4,h5,h6{color:var(--ifm-heading-color);font-family:var(--ifm-heading-font-family);font-weight:var(--ifm-heading-font-weight);line-height:var(--ifm-heading-line-height);margin:var(--ifm-heading-margin-top) 0 var(--ifm-heading-margin-bottom) 0}h1{font-size:var(--ifm-h1-font-size)}h2{font-size:var(--ifm-h2-font-size)}h3{font-size:var(--ifm-h3-font-size)}h4{font-size:var(--ifm-h4-font-size)}h5{font-size:var(--ifm-h5-font-size)}h6{font-size:var(--ifm-h6-font-size)}img{max-width:100%}img[align=right]{padding-left:var(--image-alignment-padding)}img[align=left]{padding-right:var(--image-alignment-padding)}.markdown{--ifm-h1-vertical-rhythm-top:3;--ifm-h2-vertical-rhythm-top:2;--ifm-h3-vertical-rhythm-top:1.5;--ifm-heading-vertical-rhythm-top:1.25;--ifm-h1-vertical-rhythm-bottom:1.25;--ifm-heading-vertical-rhythm-bottom:1}.markdown:after,.markdown:before{content:"";display:table}.markdown:after{clear:both}.markdown h1:first-child{--ifm-h1-font-size:3rem;margin-bottom:calc(var(--ifm-h1-vertical-rhythm-bottom)*var(--ifm-leading))}.markdown>h2{--ifm-h2-font-size:2rem;margin-top:calc(var(--ifm-h2-vertical-rhythm-top)*var(--ifm-leading))}.markdown>h3{--ifm-h3-font-size:1.5rem;margin-top:calc(var(--ifm-h3-vertical-rhythm-top)*var(--ifm-leading))}.markdown>h4,.markdown>h5,.markdown>h6{margin-top:calc(var(--ifm-heading-vertical-rhythm-top)*var(--ifm-leading))}.markdown>p,.markdown>pre,.markdown>ul{margin-bottom:var(--ifm-leading)}.markdown li>p{margin-top:var(--ifm-list-paragraph-margin)}.markdown li+li{margin-top:var(--ifm-list-item-margin)}ol,ul{margin:0 0 var(--ifm-list-margin);padding-left:var(--ifm-list-left-padding)}ol ol,ul ol{list-style-type:lower-roman}ol ol ol,ol ul ol,ul ol ol,ul ul ol{list-style-type:lower-alpha}table{border-collapse:collapse;display:block;margin-bottom:var(--ifm-spacing-vertical)}table thead tr{border-bottom:2px solid var(--ifm-table-border-color)}table thead,table tr:nth-child(2n){background-color:var(--ifm-table-stripe-background)}table tr{background-color:var(--ifm-table-background);border-top:var(--ifm-table-border-width) solid var(--ifm-table-border-color)}table td,table th{border:var(--ifm-table-border-width) solid var(--ifm-table-border-color);padding:var(--ifm-table-cell-padding)}table th{background-color:var(--ifm-table-head-background);color:var(--ifm-table-head-color);font-weight:var(--ifm-table-head-font-weight)}table td{color:var(--ifm-table-cell-color)}strong{font-weight:var(--ifm-font-weight-bold)}a{color:var(--ifm-link-color);text-decoration:var(--ifm-link-decoration)}a:hover{color:var(--ifm-link-hover-color);text-decoration:var(--ifm-link-hover-decoration)}.button:hover,.text--no-decoration,.text--no-decoration:hover,a:not([href]){text-decoration:none}p{margin:0 0 var(--ifm-paragraph-margin-bottom);max-width:560px}blockquote{border-left:var(--ifm-blockquote-border-left-width) solid var(--ifm-blockquote-border-color);box-shadow:var(--ifm-blockquote-shadow);color:var(--ifm-blockquote-color);font-size:var(--ifm-blockquote-font-size);padding:var(--ifm-blockquote-padding-vertical) var(--ifm-blockquote-padding-horizontal)}blockquote>:first-child{margin-top:0}blockquote>:last-child{margin-bottom:0}hr{background-color:var(--ifm-hr-background-color);border:0;height:var(--ifm-hr-height);margin:var(--ifm-hr-margin-vertical) 0}.shadow--lw{box-shadow:var(--ifm-global-shadow-lw)!important}.shadow--md{box-shadow:var(--ifm-global-shadow-md)!important}.shadow--tl{box-shadow:var(--ifm-global-shadow-tl)!important}.showcase-title,.text--primary,.wordWrapButtonEnabled_EoeP .wordWrapButtonIcon_Bwma{color:var(--ifm-color-primary)}.text--secondary{color:var(--ifm-color-secondary)}.text--success{color:var(--ifm-color-success)}.text--info{color:var(--ifm-color-info)}.text--warning{color:var(--ifm-color-warning)}.text--danger{color:var(--ifm-color-danger)}.text--center{text-align:center}.text--left{text-align:left}.text--justify{text-align:justify}.text--right{text-align:right}.text--capitalize{text-transform:capitalize}.text--lowercase{text-transform:lowercase}.admonitionHeading_Gvgb,.alert__heading,.btn,.text--uppercase{text-transform:uppercase}.text--light{font-weight:var(--ifm-font-weight-light)}.text--normal{font-weight:var(--ifm-font-weight-normal)}.text--semibold{font-weight:var(--ifm-font-weight-semibold)}.text--bold{font-weight:var(--ifm-font-weight-bold)}.text--italic{font-style:italic}.text--truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text--break{word-wrap:break-word!important;word-break:break-word!important}.clean-btn{background:none;border:none;color:inherit;cursor:pointer;font-family:inherit;padding:0}.alert,.alert .close{color:var(--ifm-alert-foreground-color)}.clean-list{padding-left:0}.alert--primary{--ifm-alert-background-color:var(--ifm-color-primary-contrast-background);--ifm-alert-background-color-highlight:rgba(53,120,229,.15);--ifm-alert-foreground-color:var(--ifm-color-primary-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-primary-dark)}.alert--secondary{--ifm-alert-background-color:var(--ifm-color-secondary-contrast-background);--ifm-alert-background-color-highlight:rgba(235,237,240,.15);--ifm-alert-foreground-color:var(--ifm-color-secondary-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-secondary-dark)}.alert--success{--ifm-alert-background-color:var(--ifm-color-success-contrast-background);--ifm-alert-background-color-highlight:rgba(0,164,0,.15);--ifm-alert-foreground-color:var(--ifm-color-success-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-success-dark)}.alert--info{--ifm-alert-background-color:var(--ifm-color-info-contrast-background);--ifm-alert-background-color-highlight:rgba(84,199,236,.15);--ifm-alert-foreground-color:var(--ifm-color-info-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-info-dark)}.alert--warning{--ifm-alert-background-color:var(--ifm-color-warning-contrast-background);--ifm-alert-background-color-highlight:rgba(255,186,0,.15);--ifm-alert-foreground-color:var(--ifm-color-warning-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-warning-dark)}.alert--danger{--ifm-alert-background-color:var(--ifm-color-danger-contrast-background);--ifm-alert-background-color-highlight:rgba(250,56,62,.15);--ifm-alert-foreground-color:var(--ifm-color-danger-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-danger-dark)}.alert{--ifm-code-background:var(--ifm-alert-background-color-highlight);--ifm-link-color:var(--ifm-alert-foreground-color);--ifm-link-hover-color:var(--ifm-alert-foreground-color);--ifm-link-decoration:underline;--ifm-tabs-color:var(--ifm-alert-foreground-color);--ifm-tabs-color-active:var(--ifm-alert-foreground-color);--ifm-tabs-color-active-border:var(--ifm-alert-border-color);background-color:var(--ifm-alert-background-color);border:var(--ifm-alert-border-width) solid var(--ifm-alert-border-color);border-left-width:var(--ifm-alert-border-left-width);border-radius:var(--ifm-alert-border-radius);box-shadow:var(--ifm-alert-shadow);padding:var(--ifm-alert-padding-vertical) var(--ifm-alert-padding-horizontal)}.alert__heading{align-items:center;display:flex;font:700 var(--ifm-h5-font-size)/var(--ifm-heading-line-height) var(--ifm-heading-font-family);margin-bottom:.5rem}.alert__icon{display:inline-flex;margin-right:.4em}.alert__icon svg{fill:var(--ifm-alert-foreground-color);stroke:var(--ifm-alert-foreground-color);stroke-width:0}.alert .close{margin:calc(var(--ifm-alert-padding-vertical)*-1) calc(var(--ifm-alert-padding-horizontal)*-1) 0 0;opacity:.75}.alert .close:focus,.alert .close:hover{opacity:1}.alert a{text-decoration-color:var(--ifm-alert-border-color)}.alert a:hover{text-decoration-thickness:2px}.avatar{-moz-column-gap:var(--ifm-avatar-intro-margin);column-gap:var(--ifm-avatar-intro-margin);display:flex}.avatar__photo{border-radius:50%;display:block;height:var(--ifm-avatar-photo-size);overflow:hidden;width:var(--ifm-avatar-photo-size)}.card--full-height,.navbar__logo img,body,html{height:100%}.avatar__photo--sm{--ifm-avatar-photo-size:2rem}.avatar__photo--lg{--ifm-avatar-photo-size:4rem}.avatar__photo--xl{--ifm-avatar-photo-size:6rem}.avatar__intro{display:flex;flex:1 1;flex-direction:column;justify-content:center;text-align:var(--ifm-avatar-intro-alignment)}.badge,.breadcrumbs__item,.breadcrumbs__link,.button,.dropdown>.navbar__link:after{display:inline-block}.avatar__name{font:700 var(--ifm-h4-font-size)/var(--ifm-heading-line-height) var(--ifm-font-family-base)}.avatar__subtitle{margin-top:.25rem}.avatar--vertical{--ifm-avatar-intro-alignment:center;--ifm-avatar-intro-margin:0.5rem;align-items:center;flex-direction:column}.badge{background-color:var(--ifm-badge-background-color);border:var(--ifm-badge-border-width) solid var(--ifm-badge-border-color);border-radius:var(--ifm-badge-border-radius);color:var(--ifm-badge-color);font-size:75%;font-weight:var(--ifm-font-weight-bold);line-height:1;padding:var(--ifm-badge-padding-vertical) var(--ifm-badge-padding-horizontal)}.badge--primary{--ifm-badge-background-color:var(--ifm-color-primary)}.badge--secondary{--ifm-badge-background-color:var(--ifm-color-secondary);color:var(--ifm-color-black)}.breadcrumbs__link,.button.button--secondary.button--outline:not(.button--active):not(:hover){color:var(--ifm-font-color-base)}.badge--success{--ifm-badge-background-color:var(--ifm-color-success)}.badge--info{--ifm-badge-background-color:var(--ifm-color-info)}.badge--warning{--ifm-badge-background-color:var(--ifm-color-warning)}.badge--danger{--ifm-badge-background-color:var(--ifm-color-danger)}.breadcrumbs{margin-bottom:0;padding-left:0}.breadcrumbs__item:not(:last-child):after{background:var(--ifm-breadcrumb-separator) center;content:" ";display:inline-block;filter:var(--ifm-breadcrumb-separator-filter);height:calc(var(--ifm-breadcrumb-separator-size)*var(--ifm-breadcrumb-size-multiplier)*var(--ifm-breadcrumb-separator-size-multiplier));margin:0 var(--ifm-breadcrumb-spacing);opacity:.5;width:calc(var(--ifm-breadcrumb-separator-size)*var(--ifm-breadcrumb-size-multiplier)*var(--ifm-breadcrumb-separator-size-multiplier))}.breadcrumbs__item--active .breadcrumbs__link{background:var(--ifm-breadcrumb-item-background-active);color:var(--ifm-breadcrumb-color-active)}.breadcrumbs__link{border-radius:var(--ifm-breadcrumb-border-radius);font-size:calc(1rem*var(--ifm-breadcrumb-size-multiplier));padding:calc(var(--ifm-breadcrumb-padding-vertical)*var(--ifm-breadcrumb-size-multiplier)) calc(var(--ifm-breadcrumb-padding-horizontal)*var(--ifm-breadcrumb-size-multiplier));transition-duration:var(--ifm-transition-fast);transition-property:background,color}.breadcrumbs__link:link:hover,.breadcrumbs__link:visited:hover,area[href].breadcrumbs__link:hover{background:var(--ifm-breadcrumb-item-background-active);text-decoration:none}.breadcrumbs__link:-moz-any-link:hover{background:var(--ifm-breadcrumb-item-background-active);text-decoration:none}.breadcrumbs__link:any-link:hover{background:var(--ifm-breadcrumb-item-background-active);text-decoration:none}.breadcrumbs--sm{--ifm-breadcrumb-size-multiplier:0.8}.breadcrumbs--lg{--ifm-breadcrumb-size-multiplier:1.2}.button{background-color:var(--ifm-button-background-color);border:var(--ifm-button-border-width) solid var(--ifm-button-border-color);border-radius:var(--ifm-button-border-radius);cursor:pointer;font-size:calc(.875rem*var(--ifm-button-size-multiplier));font-weight:var(--ifm-button-font-weight);line-height:1.5;padding:calc(var(--ifm-button-padding-vertical)*var(--ifm-button-size-multiplier)) calc(var(--ifm-button-padding-horizontal)*var(--ifm-button-size-multiplier));text-align:center;transition-duration:var(--ifm-button-transition-duration);transition-property:color,background,border-color;-webkit-user-select:none;-moz-user-select:none;user-select:none;white-space:nowrap}.button,.button:hover{color:var(--ifm-button-color)}.button--outline{--ifm-button-color:var(--ifm-button-border-color)}.button--outline:hover{--ifm-button-background-color:var(--ifm-button-border-color)}.button--link{--ifm-button-border-color:transparent;color:var(--ifm-link-color);text-decoration:var(--ifm-link-decoration)}.button--link.button--active,.button--link:active,.button--link:hover{color:var(--ifm-link-hover-color);text-decoration:var(--ifm-link-hover-decoration)}.button.disabled,.button:disabled,.button[disabled]{opacity:.65;pointer-events:none}.button--sm{--ifm-button-size-multiplier:0.8}.button--lg{--ifm-button-size-multiplier:1.35}.button--block{display:block;width:100%}.button.button--secondary{color:var(--ifm-color-gray-900)}:where(.button--primary){--ifm-button-background-color:var(--ifm-color-primary);--ifm-button-border-color:var(--ifm-color-primary)}:where(.button--primary):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-primary-dark);--ifm-button-border-color:var(--ifm-color-primary-dark)}.button--primary.button--active,.button--primary:active{--ifm-button-background-color:var(--ifm-color-primary-darker);--ifm-button-border-color:var(--ifm-color-primary-darker)}:where(.button--secondary){--ifm-button-background-color:var(--ifm-color-secondary);--ifm-button-border-color:var(--ifm-color-secondary)}:where(.button--secondary):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-secondary-dark);--ifm-button-border-color:var(--ifm-color-secondary-dark)}.button--secondary.button--active,.button--secondary:active{--ifm-button-background-color:var(--ifm-color-secondary-darker);--ifm-button-border-color:var(--ifm-color-secondary-darker)}:where(.button--success){--ifm-button-background-color:var(--ifm-color-success);--ifm-button-border-color:var(--ifm-color-success)}:where(.button--success):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-success-dark);--ifm-button-border-color:var(--ifm-color-success-dark)}.button--success.button--active,.button--success:active{--ifm-button-background-color:var(--ifm-color-success-darker);--ifm-button-border-color:var(--ifm-color-success-darker)}:where(.button--info){--ifm-button-background-color:var(--ifm-color-info);--ifm-button-border-color:var(--ifm-color-info)}:where(.button--info):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-info-dark);--ifm-button-border-color:var(--ifm-color-info-dark)}.button--info.button--active,.button--info:active{--ifm-button-background-color:var(--ifm-color-info-darker);--ifm-button-border-color:var(--ifm-color-info-darker)}:where(.button--warning){--ifm-button-background-color:var(--ifm-color-warning);--ifm-button-border-color:var(--ifm-color-warning)}:where(.button--warning):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-warning-dark);--ifm-button-border-color:var(--ifm-color-warning-dark)}.button--warning.button--active,.button--warning:active{--ifm-button-background-color:var(--ifm-color-warning-darker);--ifm-button-border-color:var(--ifm-color-warning-darker)}:where(.button--danger){--ifm-button-background-color:var(--ifm-color-danger);--ifm-button-border-color:var(--ifm-color-danger)}:where(.button--danger):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-danger-dark);--ifm-button-border-color:var(--ifm-color-danger-dark)}.button--danger.button--active,.button--danger:active{--ifm-button-background-color:var(--ifm-color-danger-darker);--ifm-button-border-color:var(--ifm-color-danger-darker)}.button-group{display:inline-flex;gap:var(--ifm-button-group-spacing)}.button-group>.button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.button-group>.button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.button-group--block{display:flex;justify-content:stretch}.button-group--block>.button{flex-grow:1}.card{background-color:var(--ifm-card-background-color);border-radius:var(--ifm-card-border-radius);box-shadow:var(--ifm-global-shadow-lw);display:flex;flex-direction:column;overflow:hidden}.card__image{padding-top:var(--ifm-card-vertical-spacing)}.card__image:first-child{padding-top:0}.card__body,.card__footer,.card__header{padding:var(--ifm-card-vertical-spacing) var(--ifm-card-horizontal-spacing)}.card__body:not(:last-child),.card__footer:not(:last-child),.card__header:not(:last-child){padding-bottom:0}.card__body>:last-child,.card__footer>:last-child,.card__header>:last-child{margin-bottom:0}.card__footer{margin-top:auto}.table-of-contents{font-size:.8rem;margin-bottom:0;padding:var(--ifm-toc-padding-vertical) 0}.table-of-contents,.table-of-contents ul{list-style:none;padding-left:var(--ifm-toc-padding-horizontal)}.table-of-contents li{margin:var(--ifm-toc-padding-vertical) var(--ifm-toc-padding-horizontal)}.table-of-contents__left-border{border-left:1px solid var(--ifm-toc-border-color)}.table-of-contents__link{color:var(--ifm-toc-link-color);display:block}.table-of-contents__link--active,.table-of-contents__link--active code,.table-of-contents__link:hover,.table-of-contents__link:hover code{color:var(--ifm-color-primary);text-decoration:none}.close{color:var(--ifm-color-black);float:right;font-size:1.5rem;font-weight:var(--ifm-font-weight-bold);line-height:1;opacity:.5;padding:1rem;transition:opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.close:hover{opacity:.7}.close:focus,.theme-code-block-highlighted-line .codeLineNumber_Tfdd:before{opacity:.8}.dropdown{display:inline-flex;font-weight:var(--ifm-dropdown-font-weight);position:relative;vertical-align:top}.dropdown--hoverable:hover .dropdown__menu,.dropdown--show .dropdown__menu{opacity:1;pointer-events:all;transform:translateY(-1px);visibility:visible}#nprogress,.dropdown__menu,.navbar__item.dropdown .navbar__link:not([href]){pointer-events:none}.dropdown--right .dropdown__menu{left:inherit;right:0}.dropdown--nocaret .navbar__link:after{content:none!important}.dropdown__menu{background-color:var(--ifm-dropdown-background-color);border-radius:var(--ifm-global-radius);box-shadow:var(--ifm-global-shadow-md);left:0;max-height:80vh;min-width:10rem;opacity:0;overflow-y:auto;padding:.5rem;position:absolute;top:calc(100% - var(--ifm-navbar-item-padding-vertical) + .3rem);transform:translateY(-.625rem);transition-duration:var(--ifm-transition-fast);transition-property:opacity,transform,visibility;transition-timing-function:var(--ifm-transition-timing-default);visibility:hidden;z-index:var(--ifm-z-index-dropdown)}.menu__caret,.menu__link,.menu__list-item-collapsible{border-radius:.25rem;transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.dropdown__link{border-radius:.25rem;color:var(--ifm-dropdown-link-color);display:block;font-size:.875rem;margin-top:.2rem;padding:.25rem .5rem;white-space:nowrap}.dropdown__link--active,.dropdown__link:hover{background-color:var(--ifm-dropdown-hover-background-color);color:var(--ifm-dropdown-link-color);text-decoration:none}.dropdown__link--active,.dropdown__link--active:hover{--ifm-dropdown-link-color:var(--ifm-link-color)}.dropdown>.navbar__link:after{border-color:currentcolor transparent;border-style:solid;border-width:.4em .4em 0;content:"";margin-left:.3em;position:relative;top:2px;transform:translateY(-50%)}.footer{background-color:var(--ifm-footer-background-color);color:var(--ifm-footer-color);padding:var(--ifm-footer-padding-vertical) var(--ifm-footer-padding-horizontal)}.footer--dark{--ifm-footer-background-color:#303846;--ifm-footer-color:var(--ifm-footer-link-color);--ifm-footer-link-color:var(--ifm-color-secondary);--ifm-footer-title-color:var(--ifm-color-white)}.footer__links{margin-bottom:1rem}.footer__link-item{color:var(--ifm-footer-link-color);line-height:2}.footer__link-item:hover{color:var(--ifm-footer-link-hover-color)}.footer__link-separator{margin:0 var(--ifm-footer-link-horizontal-spacing)}.footer__logo{margin-top:1rem;max-width:var(--ifm-footer-logo-max-width)}.footer__title{color:var(--ifm-footer-title-color);font:700 var(--ifm-h4-font-size)/var(--ifm-heading-line-height) var(--ifm-font-family-base);margin-bottom:var(--ifm-heading-margin-bottom)}.menu,.navbar__link{font-weight:var(--ifm-font-weight-semibold)}.docItemContainer_Djhp article>:first-child,.docItemContainer_Djhp header+*,.footer__item{margin-top:0}.admonitionContent_BuS1>:last-child,.collapsibleContent_i85q p:last-child,.details_lb9f>summary>p:last-child,.footer__items{margin-bottom:0}.codeBlockStandalone_MEMb,[type=checkbox]{padding:0}.hero{align-items:center;background-color:var(--ifm-hero-background-color);color:var(--ifm-hero-text-color);display:flex;padding:4rem 2rem}.hero--primary{--ifm-hero-background-color:var(--ifm-color-primary);--ifm-hero-text-color:var(--ifm-font-color-base-inverse)}.hero--dark{--ifm-hero-background-color:#303846;--ifm-hero-text-color:var(--ifm-color-white)}.hero__title{font-size:3rem}.hero__subtitle{font-size:1.5rem}.menu__list{margin:0;padding-left:0}.menu__caret,.menu__link{padding:var(--ifm-menu-link-padding-vertical) var(--ifm-menu-link-padding-horizontal)}.menu__list .menu__list{flex:0 0 100%;margin-top:.25rem;padding-left:var(--ifm-menu-link-padding-horizontal)}.menu__list-item:not(:first-child){margin-top:.25rem}.menu__list-item--collapsed .menu__list{height:0;overflow:hidden}.details_lb9f[data-collapsed=false].isBrowser_bmU9>summary:before,.details_lb9f[open]:not(.isBrowser_bmU9)>summary:before,.menu__list-item--collapsed .menu__caret:before,.menu__list-item--collapsed .menu__link--sublist:after{transform:rotate(90deg)}.menu__list-item-collapsible{display:flex;flex-wrap:wrap;position:relative}.menu__caret:hover,.menu__link:hover,.menu__list-item-collapsible--active,.menu__list-item-collapsible:hover{background:var(--ifm-menu-color-background-hover)}.menu__list-item-collapsible .menu__link--active,.menu__list-item-collapsible .menu__link:hover{background:none!important}.menu__caret,.menu__link{align-items:center;display:flex}.menu__link{color:var(--ifm-menu-color);flex:1;line-height:1.25}.menu__link:hover{color:var(--ifm-menu-color);text-decoration:none}.menu__caret:before,.menu__link--sublist-caret:after{content:"";height:1.25rem;transform:rotate(180deg);transition:transform var(--ifm-transition-fast) linear;width:1.25rem;filter:var(--ifm-menu-link-sublist-icon-filter)}.menu__link--sublist-caret:after{background:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem;margin-left:auto;min-width:1.25rem}.menu__link--active,.menu__link--active:hover{color:var(--ifm-menu-color-active)}.navbar__brand,.navbar__link{color:var(--ifm-navbar-link-color)}.menu__link--active:not(.menu__link--sublist){background-color:var(--ifm-menu-color-background-active)}.menu__caret:before{background:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem}.navbar--dark,html[data-theme=dark]{--ifm-menu-link-sublist-icon-filter:invert(100%) sepia(94%) saturate(17%) hue-rotate(223deg) brightness(104%) contrast(98%)}.navbar{background-color:var(--ifm-navbar-background-color);box-shadow:var(--ifm-navbar-shadow);height:var(--ifm-navbar-height);padding:var(--ifm-navbar-padding-vertical) var(--ifm-navbar-padding-horizontal)}.landing-two-block-container,.navbar,.navbar>.container,.navbar>.container-fluid{display:flex}.navbar--fixed-top{position:sticky;top:0;z-index:var(--ifm-z-index-fixed)}.navbar-sidebar,.navbar-sidebar__backdrop{bottom:0;opacity:0;position:fixed;transition-duration:var(--ifm-transition-fast);transition-timing-function:ease-in-out;left:0;top:0;visibility:hidden}.navbar__inner{display:flex;flex-wrap:wrap;justify-content:space-between;width:100%}.navbar__brand{align-items:center;display:flex;margin-right:1rem;min-width:0}.navbar__brand:hover{color:var(--ifm-navbar-link-hover-color);text-decoration:none}.announcementBarContent_xLdY,.navbar__title{flex:1 1 auto}.navbar__toggle{display:none;margin-right:.5rem}.navbar__logo{flex:0 0 auto;height:2rem;margin-right:.5rem}.navbar__items{align-items:center;display:flex;flex:1;min-width:0}.navbar__items--center{flex:0 0 auto}.highlights-item>h2,.highlights-item>p,.navbar__items--center .navbar__brand{margin:0}.navbar__items--center+.navbar__items--right{flex:1}.navbar__items--right{flex:0 0 auto;justify-content:flex-end}.navbar__items--right>:last-child{padding-right:0}.navbar__item{display:inline-block;padding:var(--ifm-navbar-item-padding-vertical) var(--ifm-navbar-item-padding-horizontal)}.navbar__link--active,.navbar__link:hover{color:var(--ifm-navbar-link-hover-color);text-decoration:none}.navbar--dark,.navbar--primary{--ifm-menu-color:var(--ifm-color-gray-300);--ifm-navbar-link-color:var(--ifm-color-gray-100);--ifm-navbar-search-input-background-color:hsla(0,0%,100%,.1);--ifm-navbar-search-input-placeholder-color:hsla(0,0%,100%,.5);color:var(--ifm-color-white)}.navbar--dark{--ifm-navbar-background-color:#242526;--ifm-menu-color-background-active:hsla(0,0%,100%,.05);--ifm-navbar-search-input-color:var(--ifm-color-white)}.navbar--primary{--ifm-navbar-background-color:var(--ifm-color-primary);--ifm-navbar-link-hover-color:var(--ifm-color-white);--ifm-menu-color-active:var(--ifm-color-white);--ifm-navbar-search-input-color:var(--ifm-color-emphasis-500)}.navbar__search-input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:var(--ifm-navbar-search-input-background-color) var(--ifm-navbar-search-input-icon) no-repeat .75rem center/1rem 1rem;border:none;border-radius:2rem;color:var(--ifm-navbar-search-input-color);cursor:text;display:inline-block;font-size:.9rem;height:2rem;padding:0 .5rem 0 2.25rem;width:12.5rem}.navbar__search-input::-moz-placeholder{color:var(--ifm-navbar-search-input-placeholder-color)}.navbar__search-input::placeholder{color:var(--ifm-navbar-search-input-placeholder-color)}.navbar-sidebar{background-color:var(--ifm-navbar-background-color);box-shadow:var(--ifm-global-shadow-md);transform:translate3d(-100%,0,0);transition-property:opacity,visibility,transform;width:var(--ifm-navbar-sidebar-width)}.navbar-sidebar--show .navbar-sidebar,.navbar-sidebar__items{transform:translateZ(0)}.navbar-sidebar--show .navbar-sidebar,.navbar-sidebar--show .navbar-sidebar__backdrop{opacity:1;visibility:visible}.navbar-sidebar__backdrop{background-color:rgba(0,0,0,.6);right:0;transition-property:opacity,visibility}.navbar-sidebar__brand{align-items:center;box-shadow:var(--ifm-navbar-shadow);display:flex;flex:1;height:var(--ifm-navbar-height);padding:var(--ifm-navbar-padding-vertical) var(--ifm-navbar-padding-horizontal)}.navbar-sidebar__items{display:flex;height:calc(100% - var(--ifm-navbar-height));transition:transform var(--ifm-transition-fast) ease-in-out}.navbar-sidebar__items--show-secondary{transform:translate3d(calc((var(--ifm-navbar-sidebar-width))*-1),0,0)}.navbar-sidebar__item{flex-shrink:0;padding:.5rem;width:calc(var(--ifm-navbar-sidebar-width))}.navbar-sidebar__back{background:var(--ifm-menu-color-background-active);font-size:15px;font-weight:var(--ifm-button-font-weight);margin:0 0 .2rem -.5rem;padding:.6rem 1.5rem;position:relative;text-align:left;top:-.5rem;width:calc(100% + 1rem)}.navbar-sidebar__close{display:flex;margin-left:auto}.pagination{-moz-column-gap:var(--ifm-pagination-page-spacing);column-gap:var(--ifm-pagination-page-spacing);display:flex;font-size:var(--ifm-pagination-font-size);padding-left:0}.pagination--sm{--ifm-pagination-font-size:0.8rem;--ifm-pagination-padding-horizontal:0.8rem;--ifm-pagination-padding-vertical:0.2rem}.pagination--lg{--ifm-pagination-font-size:1.2rem;--ifm-pagination-padding-horizontal:1.2rem;--ifm-pagination-padding-vertical:0.3rem}.pagination__item{display:inline-flex}.pagination__item>span{padding:var(--ifm-pagination-padding-vertical)}.pagination__item--active .pagination__link{color:var(--ifm-pagination-color-active)}.pagination__item--active .pagination__link,.pagination__item:not(.pagination__item--active):hover .pagination__link{background:var(--ifm-pagination-item-active-background)}.pagination__item--disabled,.pagination__item[disabled]{opacity:.25;pointer-events:none}.pagination__link{border-radius:var(--ifm-pagination-border-radius);color:var(--ifm-font-color-base);display:inline-block;padding:var(--ifm-pagination-padding-vertical) var(--ifm-pagination-padding-horizontal);transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.pagination__link:hover{text-decoration:none}.pagination-nav{grid-gap:var(--ifm-spacing-horizontal);display:grid;gap:var(--ifm-spacing-horizontal);grid-template-columns:repeat(2,1fr)}.pagination-nav__link{border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-pagination-nav-border-radius);display:block;height:100%;line-height:var(--ifm-heading-line-height);padding:var(--ifm-global-spacing);transition:border-color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.pagination-nav__link:hover{border-color:var(--ifm-pagination-nav-color-hover);text-decoration:none}.pagination-nav__link--next{grid-column:2/3;text-align:right}.pagination-nav__label{font-size:var(--ifm-h4-font-size);font-weight:var(--ifm-heading-font-weight);word-break:break-word}.pagination-nav__link--prev .pagination-nav__label:before{content:"« "}.pagination-nav__link--next .pagination-nav__label:after{content:" »"}.pagination-nav__sublabel{color:var(--ifm-color-content-secondary);font-size:var(--ifm-h5-font-size);font-weight:var(--ifm-font-weight-semibold);margin-bottom:.25rem}.pills__item,.tabs{font-weight:var(--ifm-font-weight-bold)}.pills{display:flex;gap:var(--ifm-pills-spacing);padding-left:0}.pills__item{border-radius:.5rem;cursor:pointer;display:inline-block;padding:.25rem 1rem;transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.tabs,:not(.containsTaskList_mC6p>li)>.containsTaskList_mC6p{padding-left:0}.pills__item--active{color:var(--ifm-pills-color-active)}.pills__item--active,.pills__item:not(.pills__item--active):hover{background:var(--ifm-pills-color-background-active)}.pills--block{justify-content:stretch}.pills--block .pills__item{flex-grow:1;text-align:center}.tabs{color:var(--ifm-tabs-color);display:flex;margin-bottom:0;overflow-x:auto}.tabs__item{border-bottom:3px solid transparent;border-radius:var(--ifm-global-radius);cursor:pointer;display:inline-flex;padding:var(--ifm-tabs-padding-vertical) var(--ifm-tabs-padding-horizontal);transition:background-color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.tabs__item--active{border-bottom-color:var(--ifm-tabs-color-active-border);border-bottom-left-radius:0;border-bottom-right-radius:0;color:var(--ifm-tabs-color-active)}.tabs__item:hover{background-color:var(--ifm-hover-overlay)}.tabs--block{justify-content:stretch}.tabs--block .tabs__item{flex-grow:1;justify-content:center}html[data-theme=dark]{--ifm-color-scheme:dark;--ifm-color-emphasis-0:var(--ifm-color-gray-1000);--ifm-color-emphasis-100:var(--ifm-color-gray-900);--ifm-color-emphasis-200:var(--ifm-color-gray-800);--ifm-color-emphasis-300:var(--ifm-color-gray-700);--ifm-color-emphasis-400:var(--ifm-color-gray-600);--ifm-color-emphasis-600:var(--ifm-color-gray-400);--ifm-color-emphasis-700:var(--ifm-color-gray-300);--ifm-color-emphasis-800:var(--ifm-color-gray-200);--ifm-color-emphasis-900:var(--ifm-color-gray-100);--ifm-color-emphasis-1000:var(--ifm-color-gray-0);--ifm-background-color:#1b1b1d;--ifm-background-surface-color:#242526;--ifm-hover-overlay:hsla(0,0%,100%,.05);--ifm-color-content:#e3e3e3;--ifm-color-content-secondary:#fff;--ifm-breadcrumb-separator-filter:invert(64%) sepia(11%) saturate(0%) hue-rotate(149deg) brightness(99%) contrast(95%);--ifm-code-background:hsla(0,0%,100%,.1);--ifm-scrollbar-track-background-color:#444;--ifm-scrollbar-thumb-background-color:#686868;--ifm-scrollbar-thumb-hover-background-color:#7a7a7a;--ifm-table-stripe-background:hsla(0,0%,100%,.07);--ifm-toc-border-color:var(--ifm-color-emphasis-200);--ifm-color-primary-contrast-background:#102445;--ifm-color-primary-contrast-foreground:#ebf2fc;--ifm-color-secondary-contrast-background:#474748;--ifm-color-secondary-contrast-foreground:#fdfdfe;--ifm-color-success-contrast-background:#003100;--ifm-color-success-contrast-foreground:#e6f6e6;--ifm-color-info-contrast-background:#193c47;--ifm-color-info-contrast-foreground:#eef9fd;--ifm-color-warning-contrast-background:#4d3800;--ifm-color-warning-contrast-foreground:#fff8e6;--ifm-color-danger-contrast-background:#4b1113;--ifm-color-danger-contrast-foreground:#ffebec}:root{--docusaurus-progress-bar-color:var(--ifm-color-primary);--ifm-color-primary-lightest:#03a697;--ifm-color-primary-lighter:#029385;--ifm-color-primary-light:#028d80;--ifm-color-primary:#028074;--ifm-color-primary-dark:#027368;--ifm-color-primary-darker:#026d63;--ifm-color-primary-darkest:#015a51;--ifm-section-alt1-background:#fff;--ifm-section-alt2-background:#f7f7f7;--ifm-navbar-background-color:#028074;--ifm-navbar-link-color:hsla(0,0%,100%,.85);--ifm-navbar-link-hover-color:#fff;--docusaurus-announcement-bar-height:auto;--docusaurus-tag-list-border:var(--ifm-color-emphasis-300);--docusaurus-collapse-button-bg:transparent;--docusaurus-collapse-button-bg-hover:rgba(0,0,0,.1);--doc-sidebar-width:300px;--doc-sidebar-hidden-width:30px}#nprogress .bar{background:var(--docusaurus-progress-bar-color);height:2px;left:0;position:fixed;top:0;width:100%;z-index:1031}#nprogress .peg{box-shadow:0 0 10px var(--docusaurus-progress-bar-color),0 0 5px var(--docusaurus-progress-bar-color);height:100%;opacity:1;position:absolute;right:0;transform:rotate(3deg) translateY(-4px);width:100px}[data-theme=dark]:root{--ifm-section-alt1-background:#242424;--ifm-section-alt2-background:#414141;--docusaurus-collapse-button-bg:hsla(0,0%,100%,.05);--docusaurus-collapse-button-bg-hover:hsla(0,0%,100%,.1)}section{padding:5rem 0}h2{font-weight:600}.btn{border:1px solid var(--ifm-color-primary);border-radius:3px;font-size:14px;font-weight:400;line-height:1.2em;padding:10px;transition:background .3s,color .3s}.btn-full,.btn-outline:hover{background:var(--ifm-color-primary);color:#fff}.btn-full:hover,.btn-outline{background:#fff;color:var(--ifm-color-primary)}.main-wrapper{display:flex;flex-direction:column}#__docusaurus-base-url-issue-banner-container,.landing-two-block-container>img,.themedComponent_mlkZ,[data-theme=dark] .lightToggleIcon_pyhR,[data-theme=light] .darkToggleIcon_wfgR,html[data-announcement-bar-initially-dismissed=true] .announcementBar_mb4j{display:none}.landing-two-block-content{align-items:start;display:flex;flex-direction:column;gap:1.5rem}.home-splash{background:var(--ifm-section-alt1-background);padding:6rem 0}.home-splash-container{align-items:center;display:flex;flex-direction:column;text-align:center}.home-splash-container>h2{color:var(--ifm-color-primary);font-size:2rem;font-weight:400;margin:0 0 2rem;max-width:40rem}.jumbo,.learnhow{background:var(--ifm-section-alt2-background)}.featurelist,.highlights{background:var(--ifm-section-alt1-background)}.highlights-container{-moz-column-gap:3rem;column-gap:3rem;display:flex;flex-direction:column;row-gap:5rem}.highlights-item{align-items:center;display:flex;flex-basis:100%;flex-direction:column;flex-grow:1;flex-shrink:0;gap:1.5rem;max-width:30rem;text-align:center}.highlights-item>img{max-width:30%}.opensource{background:var(--ifm-section-alt3-background);color:#fff}.featurelist-container{display:flex;flex-direction:column;gap:3rem;justify-content:space-around}.featurelist-title{color:var(--ifm-color-primary);flex-basis:100%;text-align:center}.showcase{background:var(--ifm-section-alt1-background);text-align:center}.showcase-container{align-items:center;display:flex;flex-direction:column;gap:2rem}.showcase-logos{align-items:center;display:flex;flex-direction:row;gap:30px;justify-content:center}.showcase-logos>a,.users-showcase-logos>a{background:#fff;padding:10px}.showcase-logos>a>img{max-height:110px;width:110px}.users-showcase{display:flex;flex-grow:1}.help-container,.users-showcase-container{flex-direction:column}.users-showcase-container,.users-showcase-logos{align-items:center;display:flex;justify-content:center}.users-showcase-logos{flex-direction:row;gap:20px}.users-showcase-logos>a>img{max-height:128px;width:128px}.help-container{display:flex;gap:40px}.help-three-col,.help-two-col{display:flex;flex-direction:column;gap:30px}.help-two-col>p{flex-basis:50%;max-width:none}.help-three-col>div{flex-basis:33.33%}body:not(.navigation-with-keyboard) :not(input):focus{outline:0}.skipToContent_fXgn{background-color:var(--ifm-background-surface-color);color:var(--ifm-color-emphasis-900);left:100%;padding:calc(var(--ifm-global-spacing)/2) var(--ifm-global-spacing);position:fixed;top:1rem;z-index:calc(var(--ifm-z-index-fixed) + 1)}.skipToContent_fXgn:focus{box-shadow:var(--ifm-global-shadow-md);left:1rem}.closeButton_CVFx{line-height:0;padding:0}.content_knG7{font-size:85%;padding:5px 0;text-align:center}.content_knG7 a{color:inherit;text-decoration:underline}.announcementBar_mb4j{align-items:center;background-color:var(--ifm-color-white);border-bottom:1px solid var(--ifm-color-emphasis-100);color:var(--ifm-color-black);display:flex;height:var(--docusaurus-announcement-bar-height)}.announcementBarPlaceholder_vyr4{flex:0 0 10px}.announcementBarClose_gvF7{align-self:stretch;flex:0 0 30px}.toggle_vylO{height:2rem;width:2rem}.toggleButton_gllP{align-items:center;border-radius:50%;display:flex;height:100%;justify-content:center;transition:background var(--ifm-transition-fast);width:100%}.toggleButton_gllP:hover{background:var(--ifm-color-emphasis-200)}.toggleButtonDisabled_aARS{cursor:not-allowed}.darkNavbarColorModeToggle_X3D1:hover{background:var(--ifm-color-gray-800)}[data-theme=dark] .themedComponent--dark_xIcU,[data-theme=light] .themedComponent--light_NVdE,html:not([data-theme]) .themedComponent--light_NVdE{display:initial}.iconExternalLink_nPIU{margin-left:.3rem}.dropdownNavbarItemMobile_S0Fm{cursor:pointer}.iconLanguage_nlXk{margin-right:5px;vertical-align:text-bottom}@supports selector(:has(*)){.navbarSearchContainer_Bca1:not(:has(>*)){display:none}}.navbarHideable_m1mJ{transition:transform var(--ifm-transition-fast) ease}.navbarHidden_jGov{transform:translate3d(0,calc(-100% - 2px),0)}.errorBoundaryError_a6uf{color:red;white-space:pre-wrap}.errorBoundaryFallback_VBag{color:red;padding:.55rem}.footerLogoLink_BH7S{opacity:.5;transition:opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.footerLogoLink_BH7S:hover,.hash-link:focus,:hover>.hash-link{opacity:1}.anchorWithStickyNavbar_LWe7{scroll-margin-top:calc(var(--ifm-navbar-height) + .5rem)}.anchorWithHideOnScrollNavbar_WYt5{scroll-margin-top:.5rem}.hash-link{opacity:0;padding-left:.5rem;transition:opacity var(--ifm-transition-fast);-webkit-user-select:none;-moz-user-select:none;user-select:none}.hash-link:before{content:"#"}.mainWrapper_z2l0{display:flex;flex:1 0 auto;flex-direction:column}.docusaurus-mt-lg{margin-top:3rem}#__docusaurus{display:flex;flex-direction:column;min-height:100%}.tag_zVej{border:1px solid var(--docusaurus-tag-list-border);transition:border var(--ifm-transition-fast)}.tag_zVej:hover{--docusaurus-tag-list-border:var(--ifm-link-color);text-decoration:none}.tagRegular_sFm0{border-radius:var(--ifm-global-radius);font-size:90%;padding:.2rem .5rem .3rem}.tagWithCount_h2kH{align-items:center;border-left:0;display:flex;padding:0 .5rem 0 1rem;position:relative}.tagWithCount_h2kH:after,.tagWithCount_h2kH:before{border:1px solid var(--docusaurus-tag-list-border);content:"";position:absolute;top:50%;transition:inherit}.tagWithCount_h2kH:before{border-bottom:0;border-right:0;height:1.18rem;right:100%;transform:translate(50%,-50%) rotate(-45deg);width:1.18rem}.tagWithCount_h2kH:after{border-radius:50%;height:.5rem;left:0;transform:translateY(-50%);width:.5rem}.tagWithCount_h2kH span{background:var(--ifm-color-secondary);border-radius:var(--ifm-global-radius);color:var(--ifm-color-black);font-size:.7rem;line-height:1.2;margin-left:.3rem;padding:.1rem .4rem}.tags_jXut{display:inline}.tag_QGVx{display:inline-block;margin:0 .4rem .5rem 0}.iconEdit_Z9Sw{margin-right:.3em;vertical-align:sub}.lastUpdated_JAkA{font-size:smaller;font-style:italic;margin-top:.2rem}.tocCollapsibleButton_TO0P{align-items:center;display:flex;font-size:inherit;justify-content:space-between;padding:.4rem .8rem;width:100%}.tocCollapsibleButton_TO0P:after{background:var(--ifm-menu-link-sublist-icon) 50% 50%/2rem 2rem no-repeat;content:"";filter:var(--ifm-menu-link-sublist-icon-filter);height:1.25rem;transform:rotate(180deg);transition:transform var(--ifm-transition-fast);width:1.25rem}.tocCollapsibleButtonExpanded_MG3E:after,.tocCollapsibleExpanded_sAul{transform:none}.tocCollapsible_ETCw{background-color:var(--ifm-menu-color-background-active);border-radius:var(--ifm-global-radius);margin:1rem 0}.buttonGroup__atx button,.codeBlockContainer_Ckt0{background:var(--prism-background-color);color:var(--prism-color)}.tocCollapsibleContent_vkbj>ul{border-left:none;border-top:1px solid var(--ifm-color-emphasis-300);font-size:15px;padding:.2rem 0}.tocCollapsibleContent_vkbj ul li{margin:.4rem .8rem}.tocCollapsibleContent_vkbj a{display:block}.tableOfContents_bqdL{max-height:calc(100vh - var(--ifm-navbar-height) - 2rem);overflow-y:auto;position:sticky;top:calc(var(--ifm-navbar-height) + 1rem)}.codeBlockContainer_Ckt0{border-radius:var(--ifm-code-border-radius);box-shadow:var(--ifm-global-shadow-lw);margin-bottom:var(--ifm-leading)}.codeBlockContent_biex{border-radius:inherit;direction:ltr;position:relative}.codeBlockTitle_Ktv7{border-bottom:1px solid var(--ifm-color-emphasis-300);border-top-left-radius:inherit;border-top-right-radius:inherit;font-size:var(--ifm-code-font-size);font-weight:500;padding:.75rem var(--ifm-pre-padding)}.codeBlock_bY9V{--ifm-pre-background:var(--prism-background-color);margin:0;padding:0}.codeBlockTitle_Ktv7+.codeBlockContent_biex .codeBlock_bY9V{border-top-left-radius:0;border-top-right-radius:0}.codeBlockLines_e6Vv{float:left;font:inherit;min-width:100%;padding:var(--ifm-pre-padding)}.codeBlockLinesWithNumbering_o6Pm{display:table;padding:var(--ifm-pre-padding) 0}.buttonGroup__atx{-moz-column-gap:.2rem;column-gap:.2rem;display:flex;position:absolute;right:calc(var(--ifm-pre-padding)/2);top:calc(var(--ifm-pre-padding)/2)}.buttonGroup__atx button{align-items:center;border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-global-radius);display:flex;line-height:0;opacity:0;padding:.4rem;transition:opacity var(--ifm-transition-fast) ease-in-out}.buttonGroup__atx button:focus-visible,.buttonGroup__atx button:hover{opacity:1!important}.theme-code-block:hover .buttonGroup__atx button{opacity:.4}:where(:root){--docusaurus-highlighted-code-line-bg:#484d5b}:where([data-theme=dark]){--docusaurus-highlighted-code-line-bg:#646464}.theme-code-block-highlighted-line{background-color:var(--docusaurus-highlighted-code-line-bg);display:block;margin:0 calc(var(--ifm-pre-padding)*-1);padding:0 var(--ifm-pre-padding)}.codeLine_lJS_{counter-increment:a;display:table-row}.codeLineNumber_Tfdd{background:var(--ifm-pre-background);display:table-cell;left:0;overflow-wrap:normal;padding:0 var(--ifm-pre-padding);position:sticky;text-align:right;width:1%}.codeLineNumber_Tfdd:before{content:counter(a);opacity:.4}.codeLineContent_feaV{padding-right:var(--ifm-pre-padding)}.theme-code-block:hover .copyButtonCopied_obH4{opacity:1!important}.copyButtonIcons_eSgA{height:1.125rem;position:relative;width:1.125rem}.copyButtonIcon_y97N,.copyButtonSuccessIcon_LjdS{fill:currentColor;height:inherit;left:0;opacity:inherit;position:absolute;top:0;transition:all var(--ifm-transition-fast) ease;width:inherit}.copyButtonSuccessIcon_LjdS{color:#00d600;left:50%;opacity:0;top:50%;transform:translate(-50%,-50%) scale(.33)}.copyButtonCopied_obH4 .copyButtonIcon_y97N{opacity:0;transform:scale(.33)}.copyButtonCopied_obH4 .copyButtonSuccessIcon_LjdS{opacity:1;transform:translate(-50%,-50%) scale(1);transition-delay:75ms}.wordWrapButtonIcon_Bwma{height:1.2rem;width:1.2rem}.details_lb9f{--docusaurus-details-summary-arrow-size:0.38rem;--docusaurus-details-transition:transform 200ms ease;--docusaurus-details-decoration-color:grey}.details_lb9f>summary{cursor:pointer;padding-left:1rem;position:relative}.details_lb9f>summary::-webkit-details-marker{display:none}.details_lb9f>summary:before{border-color:transparent transparent transparent var(--docusaurus-details-decoration-color);border-style:solid;border-width:var(--docusaurus-details-summary-arrow-size);content:"";left:0;position:absolute;top:.45rem;transform:rotate(0);transform-origin:calc(var(--docusaurus-details-summary-arrow-size)/2) 50%;transition:var(--docusaurus-details-transition)}.collapsibleContent_i85q{border-top:1px solid var(--docusaurus-details-decoration-color);margin-top:1rem;padding-top:1rem}.details_b_Ee{--docusaurus-details-decoration-color:var(--ifm-alert-border-color);--docusaurus-details-transition:transform var(--ifm-transition-fast) ease;border:1px solid var(--ifm-alert-border-color);margin:0 0 var(--ifm-spacing-vertical)}.img_ev3q{height:auto}.admonition_xJq3{margin-bottom:1em}.admonitionHeading_Gvgb{font:var(--ifm-heading-font-weight) var(--ifm-h5-font-size)/var(--ifm-heading-line-height) var(--ifm-heading-font-family)}.admonitionHeading_Gvgb:not(:last-child){margin-bottom:.3rem}.admonitionHeading_Gvgb code{text-transform:none}.admonitionIcon_Rf37{display:inline-block;margin-right:.4em;vertical-align:middle}.admonitionIcon_Rf37 svg{fill:var(--ifm-alert-foreground-color);display:inline-block;height:1.6em;width:1.6em}.breadcrumbHomeIcon_YNFT{height:1.1rem;position:relative;top:1px;vertical-align:top;width:1.1rem}.breadcrumbsContainer_Z_bl{--ifm-breadcrumb-size-multiplier:0.8;margin-bottom:.8rem}.backToTopButton_sjWU{background-color:var(--ifm-color-emphasis-200);border-radius:50%;bottom:1.3rem;box-shadow:var(--ifm-global-shadow-lw);height:3rem;opacity:0;position:fixed;right:1.3rem;transform:scale(0);transition:all var(--ifm-transition-fast) var(--ifm-transition-timing-default);visibility:hidden;width:3rem;z-index:calc(var(--ifm-z-index-fixed) - 1)}.backToTopButton_sjWU:after{background-color:var(--ifm-color-emphasis-1000);content:" ";display:inline-block;height:100%;-webkit-mask:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem no-repeat;mask:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem no-repeat;width:100%}.backToTopButtonShow_xfvO{opacity:1;transform:scale(1);visibility:visible}.collapseSidebarButton_PEFL{display:none;margin:0}.docSidebarContainer_YfHR,.sidebarLogo_isFc{display:none}.docMainContainer_TBSr,.docRoot_UBD9{display:flex;width:100%}.docsWrapper_hBAB{display:flex;flex:1 0 auto}@media only screen and (min-width:736px){.landing-two-block-container{align-items:center;flex-direction:row;justify-content:space-around}.landing-two-block-container>img{display:block;margin-right:40px;max-width:500px;width:50%}.highlights-container{flex-direction:row;flex-wrap:wrap;justify-content:center}.highlights-item{flex-basis:40%}.featurelist-container{flex-direction:row;flex-wrap:wrap}.help-three-col,.help-two-col{flex-direction:row}}@media (min-width:997px){.collapseSidebarButton_PEFL,.expandButton_TmdG{background-color:var(--docusaurus-collapse-button-bg)}:root{--docusaurus-announcement-bar-height:30px}.announcementBarClose_gvF7,.announcementBarPlaceholder_vyr4{flex-basis:50px}.navbarSearchContainer_Bca1{padding:var(--ifm-navbar-item-padding-vertical) var(--ifm-navbar-item-padding-horizontal)}.lastUpdated_JAkA{text-align:right}.tocMobile_ITEo{display:none}.docItemCol_VOVn{max-width:75%!important}.collapseSidebarButton_PEFL{border:1px solid var(--ifm-toc-border-color);border-radius:0;bottom:0;display:block!important;height:40px;position:sticky}.collapseSidebarButtonIcon_kv0_{margin-top:4px;transform:rotate(180deg)}.expandButtonIcon_i1dp,[dir=rtl] .collapseSidebarButtonIcon_kv0_{transform:rotate(0)}.collapseSidebarButton_PEFL:focus,.collapseSidebarButton_PEFL:hover,.expandButton_TmdG:focus,.expandButton_TmdG:hover{background-color:var(--docusaurus-collapse-button-bg-hover)}.menuHtmlItem_M9Kj{padding:var(--ifm-menu-link-padding-vertical) var(--ifm-menu-link-padding-horizontal)}.menu_SIkG{flex-grow:1;padding:.5rem}@supports (scrollbar-gutter:stable){.menu_SIkG{padding:.5rem 0 .5rem .5rem;scrollbar-gutter:stable}}.menuWithAnnouncementBar_GW3s{margin-bottom:var(--docusaurus-announcement-bar-height)}.sidebar_njMd{display:flex;flex-direction:column;height:100%;padding-top:var(--ifm-navbar-height);width:var(--doc-sidebar-width)}.sidebarWithHideableNavbar_wUlq{padding-top:0}.sidebarHidden_VK0M{opacity:0;visibility:hidden}.sidebarLogo_isFc{align-items:center;color:inherit!important;display:flex!important;margin:0 var(--ifm-navbar-padding-horizontal);max-height:var(--ifm-navbar-height);min-height:var(--ifm-navbar-height);text-decoration:none!important}.sidebarLogo_isFc img{height:2rem;margin-right:.5rem}.expandButton_TmdG{align-items:center;display:flex;height:100%;justify-content:center;position:absolute;right:0;top:0;transition:background-color var(--ifm-transition-fast) ease;width:100%}[dir=rtl] .expandButtonIcon_i1dp{transform:rotate(180deg)}.docSidebarContainer_YfHR{border-right:1px solid var(--ifm-toc-border-color);-webkit-clip-path:inset(0);clip-path:inset(0);display:block;margin-top:calc(var(--ifm-navbar-height)*-1);transition:width var(--ifm-transition-fast) ease;width:var(--doc-sidebar-width);will-change:width}.docSidebarContainerHidden_DPk8{cursor:pointer;width:var(--doc-sidebar-hidden-width)}.sidebarViewport_aRkj{height:100%;max-height:100vh;position:sticky;top:0}.docMainContainer_TBSr{flex-grow:1;max-width:calc(100% - var(--doc-sidebar-width))}.docMainContainerEnhanced_lQrH{max-width:calc(100% - var(--doc-sidebar-hidden-width))}.docItemWrapperEnhanced_JWYK{max-width:calc(var(--ifm-container-width) + var(--doc-sidebar-width))!important}}@media (min-width:1440px){.container{max-width:var(--ifm-container-width-xl)}}@media only screen and (min-width:1500px){section>.container{margin:auto;max-width:1400px}}@media (max-width:996px){.col{--ifm-col-width:100%;flex-basis:var(--ifm-col-width);margin-left:0}.footer{--ifm-footer-padding-horizontal:0}.colorModeToggle_DEke,.footer__link-separator,.navbar__item,.tableOfContents_bqdL{display:none}.footer__col{margin-bottom:calc(var(--ifm-spacing-vertical)*3)}.footer__link-item{display:block}.hero{padding-left:0;padding-right:0}.navbar>.container,.navbar>.container-fluid{padding:0}.navbar__toggle{display:inherit}.navbar__search-input{width:9rem}.pills--block,.tabs--block{flex-direction:column}.navbarSearchContainer_Bca1{position:absolute;right:var(--ifm-navbar-padding-horizontal)}.docItemContainer_F8PC{padding:0 .3rem}}@media (max-width:576px){.markdown h1:first-child{--ifm-h1-font-size:2rem}.markdown>h2{--ifm-h2-font-size:1.5rem}.markdown>h3{--ifm-h3-font-size:1.25rem}}@media (hover:hover){.backToTopButton_sjWU:hover{background-color:var(--ifm-color-emphasis-300)}}@media (pointer:fine){.thin-scrollbar{scrollbar-width:thin}.thin-scrollbar::-webkit-scrollbar{height:var(--ifm-scrollbar-size);width:var(--ifm-scrollbar-size)}.thin-scrollbar::-webkit-scrollbar-track{background:var(--ifm-scrollbar-track-background-color);border-radius:10px}.thin-scrollbar::-webkit-scrollbar-thumb{background:var(--ifm-scrollbar-thumb-background-color);border-radius:10px}.thin-scrollbar::-webkit-scrollbar-thumb:hover{background:var(--ifm-scrollbar-thumb-hover-background-color)}}@media (prefers-reduced-motion:reduce){:root{--ifm-transition-fast:0ms;--ifm-transition-slow:0ms}}@media print{.announcementBar_mb4j,.footer,.menu,.navbar,.pagination-nav,.table-of-contents,.tocMobile_ITEo{display:none}.tabs{page-break-inside:avoid}.codeBlockLines_e6Vv{white-space:pre-wrap}} \ No newline at end of file diff --git a/assets/js/000b5b65.7843b4ce.js b/assets/js/000b5b65.7843b4ce.js new file mode 100644 index 0000000000..43245c5405 --- /dev/null +++ b/assets/js/000b5b65.7843b4ce.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[7523],{3223:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>c,default:()=>h,frontMatter:()=>o,metadata:()=>t,toc:()=>d});var i=s(85893),r=s(11151);const o={id:"lms-backends",title:"Configuring LMS Backends",sidebar_label:"LMS Backends"},c=void 0,t={id:"lms-backends",title:"Configuring LMS Backends",description:"Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless",source:"@site/versioned_docs/version-2.25.0/lms-backends.md",sourceDirName:".",slug:"/lms-backends",permalink:"/docs/lms-backends",draft:!1,unlisted:!1,tags:[],version:"2.25.0",lastUpdatedBy:"Manuel Raynaud",lastUpdatedAt:1712836499e3,frontMatter:{id:"lms-backends",title:"Configuring LMS Backends",sidebar_label:"LMS Backends"}},l={},d=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Configuring the LMS handler",id:"configuring-the-lms-handler",level:2},{value:"BASE_URL",id:"base_url",level:3},{value:"BACKEND",id:"backend",level:3},{value:"COURSE_REGEX",id:"course_regex",level:3},{value:"JS_BACKEND",id:"js_backend",level:3},{value:"JS_COURSE_REGEX",id:"js_course_regex",level:3},{value:"DEFAULT_COURSE_RUN_SYNC_MODE",id:"default_course_run_sync_mode",level:3},{value:"COURSE_RUN_SYNC_NO_UPDATE_FIELDS",id:"course_run_sync_no_update_fields",level:3},{value:"Technical support",id:"technical-support",level:2}];function a(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.p,{children:"Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless\nexperience between browsing the course catalog on Richie, enrolling to a course and following the\ncourse itself on the LMS."}),"\n",(0,i.jsx)(n.p,{children:"It is possible to do the same with Moodle or any other LMS exposing an enrollment API, at the\ncost of writing a custom LMS handler backend."}),"\n",(0,i.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsxs)(n.p,{children:["This connection requires that Richie and OpenEdX be hosted on sibling domains i.e. domains that\nare both subdomains of the same root domain, e.g. ",(0,i.jsx)(n.code,{children:"richie.example.com"})," and ",(0,i.jsx)(n.code,{children:"lms.example.com"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"OpenEdX will need to generate a CORS CSRF Cookie and this cookie is flagged as secure, which\nimplies that we are not able to use it without SSL connections."}),"\n",(0,i.jsx)(n.p,{children:"As a consequence, you need to configure your OpenEdX instance as follows:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'FEATURES = {\n ...\n "ENABLE_CORS_HEADERS": True,\n "ENABLE_CROSS_DOMAIN_CSRF_COOKIE": True,\n}\n\nCORS_ALLOW_CREDENTIALS = True\nCORS_ALLOW_INSECURE = False\nCORS_ORIGIN_WHITELIST: ["richie.example.com"] # The domain on which Richie is hosted\n\nCROSS_DOMAIN_CSRF_COOKIE_DOMAIN = ".example.com" # The parent domain shared by Richie and OpenEdX\nCROSS_DOMAIN_CSRF_COOKIE_NAME: "edx_csrf_token"\nSESSION_COOKIE_NAME: "edx_session"\n'})}),"\n",(0,i.jsx)(n.h2,{id:"configuring-the-lms-handler",children:"Configuring the LMS handler"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"LMSHandler"})," utility acts as a proxy that routes queries to the correct LMS backend API,\nbased on a regex match on the URL of the course. It is configured via the ",(0,i.jsx)(n.code,{children:"RICHIE_LMS_BACKENDS"}),"\nsetting. As an example, here is how it would be configured to connect to an Ironwood OpenEdX\ninstance hosted on ",(0,i.jsx)(n.code,{children:"https://lms.example.com"}),":"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'RICHIE_LMS_BACKENDS=[\n {\n "BASE_URL": "https://lms.example.com",\n # Django\n "BACKEND": "richie.apps.courses.lms.edx.EdXLMSBackend",\n "COURSE_REGEX": r"^https://lms\\.example\\.com/courses/(?P.*)/course/?$",\n # ReactJS\n "JS_BACKEND": "openedx-hawthorn",\n "JS_COURSE_REGEX": r"^https://lms\\.example\\.com/courses/(.*)/course/?$",\n # Course runs synchronization\n "COURSE_RUN_SYNC_NO_UPDATE_FIELDS": [],\n "DEFAULT_COURSE_RUN_SYNC_MODE": "sync_to_public",\n },\n]\n'})}),"\n",(0,i.jsx)(n.p,{children:"The following should help you understand how to configure this setting:"}),"\n",(0,i.jsx)(n.h3,{id:"base_url",children:"BASE_URL"}),"\n",(0,i.jsx)(n.p,{children:"The base url on which the OpenEdX instance is hosted. This is used to construct the complete url\nof the API endpoint on which the enrollment request is made by Richie's frontend application."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type: string"}),"\n",(0,i.jsx)(n.li,{children:"Required: Yes"}),"\n",(0,i.jsxs)(n.li,{children:["Value: for example ",(0,i.jsx)(n.a,{href:"https://lms.example.com",children:"https://lms.example.com"})]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"backend",children:"BACKEND"}),"\n",(0,i.jsx)(n.p,{children:"The path to a Python class serving as LMS backend for the targeted LMS."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type: string"}),"\n",(0,i.jsx)(n.li,{children:"Required: Yes"}),"\n",(0,i.jsxs)(n.li,{children:["Value: Richie ships with the following Python backends (custom backends can be written to fit\nanother specific LMS):","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"richie.apps.courses.lms.edx.EdXLMSBackend"}),": backend for OpenEdX"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"richie.apps.courses.lms.base.BaseLMSBackend"}),": fake backend for development purposes"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"course_regex",children:"COURSE_REGEX"}),"\n",(0,i.jsxs)(n.p,{children:["A Python regex that should match the course syllabus urls of the targeted LMS and return a\n",(0,i.jsx)(n.code,{children:"course_id"})," named group on the id of the course extracted from these urls."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type: string"}),"\n",(0,i.jsx)(n.li,{children:"Required: Yes"}),"\n",(0,i.jsxs)(n.li,{children:["Value: for example ",(0,i.jsx)(n.code,{children:"^.*/courses/(?P.*)/course/?$"})]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"js_backend",children:"JS_BACKEND"}),"\n",(0,i.jsx)(n.p,{children:"The name of the ReactJS backend to use for the targeted LMS."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type: string"}),"\n",(0,i.jsx)(n.li,{children:"Required: Yes"}),"\n",(0,i.jsxs)(n.li,{children:["Value: Richie ships with the following Javascript backends (custom backends can be written to\nfit another specific LMS):","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"openedx-dogwood"}),": backend for OpenEdX versions equal to ",(0,i.jsx)(n.code,{children:"dogwood"})," or ",(0,i.jsx)(n.code,{children:"eucalyptus"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"openedx-hawthorn"}),": backend for OpenEdX versions equal to ",(0,i.jsx)(n.code,{children:"hawthorn"})," or higher"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"openedx-fonzie"}),": backend for OpenEdX via ",(0,i.jsx)(n.a,{href:"https://github.com/openfun/fonzie",children:"Fonzie"}),"\n(extra user info and JWT tokens)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"dummy"}),": fake backend for development purposes"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"js_course_regex",children:"JS_COURSE_REGEX"}),"\n",(0,i.jsx)(n.p,{children:"A Javascript regex that should match the course syllabus urls of the targeted LMS and return an\nunnamed group on the id of the course extracted from these urls."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type: string"}),"\n",(0,i.jsx)(n.li,{children:"Required: Yes"}),"\n",(0,i.jsxs)(n.li,{children:["Value: for example ",(0,i.jsx)(n.code,{children:"^.*/courses/(.*)/course/?$"})]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"default_course_run_sync_mode",children:"DEFAULT_COURSE_RUN_SYNC_MODE"}),"\n",(0,i.jsxs)(n.p,{children:["When a course run is created, this setting is used to set the value of the ",(0,i.jsx)(n.code,{children:"sync_mode"})," field.\nThis value defines how the course runs synchronization script will impact this course run after\ncreation."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type: enum(string)"}),"\n",(0,i.jsx)(n.li,{children:"Required: No"}),"\n",(0,i.jsxs)(n.li,{children:["Value: possible values are ",(0,i.jsx)(n.code,{children:"manual"}),", ",(0,i.jsx)(n.code,{children:"sync_to_draft"})," and ",(0,i.jsx)(n.code,{children:"sync_to_public"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"manual"}),": this course run is ignored by the course runs synchronization script"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"sync_to_draft"}),": only the draft version of this course run is synchronized. A manual\npublication is necessary for the update to be visible on the public site."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"sync_to_public"}),": the public version of this course run is updated by the synchronization\nscript. As a results, updates are directly visible on the public site without further\npublication by a staff user in Richie."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"course_run_sync_no_update_fields",children:"COURSE_RUN_SYNC_NO_UPDATE_FIELDS"}),"\n",(0,i.jsx)(n.p,{children:"A list of fields that must only be set the first time a course run is synchronized. During this\nfirst synchronization, a new course run is created in Richie and all fields sent to the API\nendpoint via the payload are set on the object. For subsequent synchronization calls, the fields\nlisted in this setting are ignored and not synchronized. This can be used to allow modifying some\nfields manually in Richie regardless of what OpenEdX sends after an initial value is set."}),"\n",(0,i.jsxs)(n.p,{children:["Note that this setting is only effective for course runs with the ",(0,i.jsx)(n.code,{children:"sync_mode"})," field set to a\nvalue other then ",(0,i.jsx)(n.code,{children:"manual"}),"."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type: enum(string)"}),"\n",(0,i.jsx)(n.li,{children:"Required: No"}),"\n",(0,i.jsx)(n.li,{children:'Value: for example ["languages"]'}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"technical-support",children:"Technical support"}),"\n",(0,i.jsxs)(n.p,{children:["If you encounter an issue with this documentation or the backends included in Richie, please\n",(0,i.jsx)(n.a,{href:"https://github.com/openfun/richie/issues",children:"open an issue on our repository"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["If you need a custom backend, you can ",(0,i.jsx)(n.a,{href:"https://github.com/openfun/richie/pulls",children:"submit a PR"})," or\n",(0,i.jsx)(n.a,{href:"https://github.com/openfun/richie/issues",children:"open an issue"})," and we will consider adding it."]})]})}function h(e={}){const{wrapper:n}={...(0,r.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},11151:(e,n,s)=>{s.d(n,{Z:()=>t,a:()=>c});var i=s(67294);const r={},o=i.createContext(r);function c(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/000b5b65.b1fe522f.js b/assets/js/000b5b65.b1fe522f.js deleted file mode 100644 index fb783407c4..0000000000 --- a/assets/js/000b5b65.b1fe522f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[7523],{3223:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>h,frontMatter:()=>o,metadata:()=>t,toc:()=>l});var i=s(85893),r=s(11151);const o={id:"lms-backends",title:"Configuring LMS Backends",sidebar_label:"LMS Backends"},c=void 0,t={id:"lms-backends",title:"Configuring LMS Backends",description:"Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless",source:"@site/versioned_docs/version-2.25.0/lms-backends.md",sourceDirName:".",slug:"/lms-backends",permalink:"/docs/lms-backends",draft:!1,unlisted:!1,tags:[],version:"2.25.0",lastUpdatedBy:"Manuel Raynaud",lastUpdatedAt:1712836499,formattedLastUpdatedAt:"Apr 11, 2024",frontMatter:{id:"lms-backends",title:"Configuring LMS Backends",sidebar_label:"LMS Backends"}},d={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Configuring the LMS handler",id:"configuring-the-lms-handler",level:2},{value:"BASE_URL",id:"base_url",level:3},{value:"BACKEND",id:"backend",level:3},{value:"COURSE_REGEX",id:"course_regex",level:3},{value:"JS_BACKEND",id:"js_backend",level:3},{value:"JS_COURSE_REGEX",id:"js_course_regex",level:3},{value:"DEFAULT_COURSE_RUN_SYNC_MODE",id:"default_course_run_sync_mode",level:3},{value:"COURSE_RUN_SYNC_NO_UPDATE_FIELDS",id:"course_run_sync_no_update_fields",level:3},{value:"Technical support",id:"technical-support",level:2}];function a(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.p,{children:"Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless\nexperience between browsing the course catalog on Richie, enrolling to a course and following the\ncourse itself on the LMS."}),"\n",(0,i.jsx)(n.p,{children:"It is possible to do the same with Moodle or any other LMS exposing an enrollment API, at the\ncost of writing a custom LMS handler backend."}),"\n",(0,i.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsxs)(n.p,{children:["This connection requires that Richie and OpenEdX be hosted on sibling domains i.e. domains that\nare both subdomains of the same root domain, e.g. ",(0,i.jsx)(n.code,{children:"richie.example.com"})," and ",(0,i.jsx)(n.code,{children:"lms.example.com"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"OpenEdX will need to generate a CORS CSRF Cookie and this cookie is flagged as secure, which\nimplies that we are not able to use it without SSL connections."}),"\n",(0,i.jsx)(n.p,{children:"As a consequence, you need to configure your OpenEdX instance as follows:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'FEATURES = {\n ...\n "ENABLE_CORS_HEADERS": True,\n "ENABLE_CROSS_DOMAIN_CSRF_COOKIE": True,\n}\n\nCORS_ALLOW_CREDENTIALS = True\nCORS_ALLOW_INSECURE = False\nCORS_ORIGIN_WHITELIST: ["richie.example.com"] # The domain on which Richie is hosted\n\nCROSS_DOMAIN_CSRF_COOKIE_DOMAIN = ".example.com" # The parent domain shared by Richie and OpenEdX\nCROSS_DOMAIN_CSRF_COOKIE_NAME: "edx_csrf_token"\nSESSION_COOKIE_NAME: "edx_session"\n'})}),"\n",(0,i.jsx)(n.h2,{id:"configuring-the-lms-handler",children:"Configuring the LMS handler"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"LMSHandler"})," utility acts as a proxy that routes queries to the correct LMS backend API,\nbased on a regex match on the URL of the course. It is configured via the ",(0,i.jsx)(n.code,{children:"RICHIE_LMS_BACKENDS"}),"\nsetting. As an example, here is how it would be configured to connect to an Ironwood OpenEdX\ninstance hosted on ",(0,i.jsx)(n.code,{children:"https://lms.example.com"}),":"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'RICHIE_LMS_BACKENDS=[\n {\n "BASE_URL": "https://lms.example.com",\n # Django\n "BACKEND": "richie.apps.courses.lms.edx.EdXLMSBackend",\n "COURSE_REGEX": r"^https://lms\\.example\\.com/courses/(?P.*)/course/?$",\n # ReactJS\n "JS_BACKEND": "openedx-hawthorn",\n "JS_COURSE_REGEX": r"^https://lms\\.example\\.com/courses/(.*)/course/?$",\n # Course runs synchronization\n "COURSE_RUN_SYNC_NO_UPDATE_FIELDS": [],\n "DEFAULT_COURSE_RUN_SYNC_MODE": "sync_to_public",\n },\n]\n'})}),"\n",(0,i.jsx)(n.p,{children:"The following should help you understand how to configure this setting:"}),"\n",(0,i.jsx)(n.h3,{id:"base_url",children:"BASE_URL"}),"\n",(0,i.jsx)(n.p,{children:"The base url on which the OpenEdX instance is hosted. This is used to construct the complete url\nof the API endpoint on which the enrollment request is made by Richie's frontend application."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type: string"}),"\n",(0,i.jsx)(n.li,{children:"Required: Yes"}),"\n",(0,i.jsxs)(n.li,{children:["Value: for example ",(0,i.jsx)(n.a,{href:"https://lms.example.com",children:"https://lms.example.com"})]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"backend",children:"BACKEND"}),"\n",(0,i.jsx)(n.p,{children:"The path to a Python class serving as LMS backend for the targeted LMS."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type: string"}),"\n",(0,i.jsx)(n.li,{children:"Required: Yes"}),"\n",(0,i.jsxs)(n.li,{children:["Value: Richie ships with the following Python backends (custom backends can be written to fit\nanother specific LMS):","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"richie.apps.courses.lms.edx.EdXLMSBackend"}),": backend for OpenEdX"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"richie.apps.courses.lms.base.BaseLMSBackend"}),": fake backend for development purposes"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"course_regex",children:"COURSE_REGEX"}),"\n",(0,i.jsxs)(n.p,{children:["A Python regex that should match the course syllabus urls of the targeted LMS and return a\n",(0,i.jsx)(n.code,{children:"course_id"})," named group on the id of the course extracted from these urls."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type: string"}),"\n",(0,i.jsx)(n.li,{children:"Required: Yes"}),"\n",(0,i.jsxs)(n.li,{children:["Value: for example ",(0,i.jsx)(n.code,{children:"^.*/courses/(?P.*)/course/?$"})]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"js_backend",children:"JS_BACKEND"}),"\n",(0,i.jsx)(n.p,{children:"The name of the ReactJS backend to use for the targeted LMS."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type: string"}),"\n",(0,i.jsx)(n.li,{children:"Required: Yes"}),"\n",(0,i.jsxs)(n.li,{children:["Value: Richie ships with the following Javascript backends (custom backends can be written to\nfit another specific LMS):","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"openedx-dogwood"}),": backend for OpenEdX versions equal to ",(0,i.jsx)(n.code,{children:"dogwood"})," or ",(0,i.jsx)(n.code,{children:"eucalyptus"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"openedx-hawthorn"}),": backend for OpenEdX versions equal to ",(0,i.jsx)(n.code,{children:"hawthorn"})," or higher"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"openedx-fonzie"}),": backend for OpenEdX via ",(0,i.jsx)(n.a,{href:"https://github.com/openfun/fonzie",children:"Fonzie"}),"\n(extra user info and JWT tokens)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"dummy"}),": fake backend for development purposes"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"js_course_regex",children:"JS_COURSE_REGEX"}),"\n",(0,i.jsx)(n.p,{children:"A Javascript regex that should match the course syllabus urls of the targeted LMS and return an\nunnamed group on the id of the course extracted from these urls."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type: string"}),"\n",(0,i.jsx)(n.li,{children:"Required: Yes"}),"\n",(0,i.jsxs)(n.li,{children:["Value: for example ",(0,i.jsx)(n.code,{children:"^.*/courses/(.*)/course/?$"})]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"default_course_run_sync_mode",children:"DEFAULT_COURSE_RUN_SYNC_MODE"}),"\n",(0,i.jsxs)(n.p,{children:["When a course run is created, this setting is used to set the value of the ",(0,i.jsx)(n.code,{children:"sync_mode"})," field.\nThis value defines how the course runs synchronization script will impact this course run after\ncreation."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type: enum(string)"}),"\n",(0,i.jsx)(n.li,{children:"Required: No"}),"\n",(0,i.jsxs)(n.li,{children:["Value: possible values are ",(0,i.jsx)(n.code,{children:"manual"}),", ",(0,i.jsx)(n.code,{children:"sync_to_draft"})," and ",(0,i.jsx)(n.code,{children:"sync_to_public"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"manual"}),": this course run is ignored by the course runs synchronization script"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"sync_to_draft"}),": only the draft version of this course run is synchronized. A manual\npublication is necessary for the update to be visible on the public site."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"sync_to_public"}),": the public version of this course run is updated by the synchronization\nscript. As a results, updates are directly visible on the public site without further\npublication by a staff user in Richie."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"course_run_sync_no_update_fields",children:"COURSE_RUN_SYNC_NO_UPDATE_FIELDS"}),"\n",(0,i.jsx)(n.p,{children:"A list of fields that must only be set the first time a course run is synchronized. During this\nfirst synchronization, a new course run is created in Richie and all fields sent to the API\nendpoint via the payload are set on the object. For subsequent synchronization calls, the fields\nlisted in this setting are ignored and not synchronized. This can be used to allow modifying some\nfields manually in Richie regardless of what OpenEdX sends after an initial value is set."}),"\n",(0,i.jsxs)(n.p,{children:["Note that this setting is only effective for course runs with the ",(0,i.jsx)(n.code,{children:"sync_mode"})," field set to a\nvalue other then ",(0,i.jsx)(n.code,{children:"manual"}),"."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type: enum(string)"}),"\n",(0,i.jsx)(n.li,{children:"Required: No"}),"\n",(0,i.jsx)(n.li,{children:'Value: for example ["languages"]'}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"technical-support",children:"Technical support"}),"\n",(0,i.jsxs)(n.p,{children:["If you encounter an issue with this documentation or the backends included in Richie, please\n",(0,i.jsx)(n.a,{href:"https://github.com/openfun/richie/issues",children:"open an issue on our repository"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["If you need a custom backend, you can ",(0,i.jsx)(n.a,{href:"https://github.com/openfun/richie/pulls",children:"submit a PR"})," or\n",(0,i.jsx)(n.a,{href:"https://github.com/openfun/richie/issues",children:"open an issue"})," and we will consider adding it."]})]})}function h(e={}){const{wrapper:n}={...(0,r.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},11151:(e,n,s)=>{s.d(n,{Z:()=>t,a:()=>c});var i=s(67294);const r={},o=i.createContext(r);function c(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/00936db6.43128f3e.js b/assets/js/00936db6.43128f3e.js deleted file mode 100644 index c7bb12900d..0000000000 --- a/assets/js/00936db6.43128f3e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[64513],{7586:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>a,toc:()=>c});var s=i(85893),t=i(11151);const o={id:"displaying-connection-status",title:"Displaying OpenEdX connection status in Richie",sidebar_label:"Displaying connection status"},r=void 0,a={id:"displaying-connection-status",title:"Displaying OpenEdX connection status in Richie",description:"This guide explains how to configure Richie and OpenEdX to share the OpenEdX connection status",source:"@site/versioned_docs/version-2.8.1/displaying-connection-status.md",sourceDirName:".",slug:"/displaying-connection-status",permalink:"/docs/2.8.1/displaying-connection-status",draft:!1,unlisted:!1,tags:[],version:"2.8.1",lastUpdatedBy:"Mehdi Benadda",lastUpdatedAt:1655108611,formattedLastUpdatedAt:"Jun 13, 2022",frontMatter:{id:"displaying-connection-status",title:"Displaying OpenEdX connection status in Richie",sidebar_label:"Displaying connection status"}},l={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Allow redirects",id:"allow-redirects",level:2},{value:"Configure authentication delegation",id:"configure-authentication-delegation",level:2},{value:"BASE_URL",id:"base_url",level:3},{value:"BACKEND",id:"backend",level:3},{value:"PROFILE_URLS",id:"profile_urls",level:3}];function d(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,t.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:"This guide explains how to configure Richie and OpenEdX to share the OpenEdX connection status\nand display profile information for the logged-in user in Richie."}),"\n",(0,s.jsx)(n.p,{children:"In Richie, the only users that are actually authenticated on the DjangoCMS instance producing the\nsite, are editors and staff users. Your instructors and learners will not have user accounts on\nRichie, but authentication is delegated to a remote service that can be OpenEdX, KeyCloack, or\nyour own centralized identity management service."}),"\n",(0,s.jsx)(n.p,{children:"In the following, we will explain how to use OpenEdX as your authentication delegation service."}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsx)(n.p,{children:"Richie will need to make CORS requests to the OpenEdX instance. As a consequence, you need to\nactivate CORS requests on your OpenEdX instance:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'FEATURES = {\n ...\n "ENABLE_CORS_HEADERS": True,\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"Then, make sure the following settings are set as follows on your OpenEdX instance:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'CORS_ALLOW_CREDENTIALS = True\nCORS_ALLOW_INSECURE = False\nCORS_ORIGIN_ALLOW_ALL = False\nCORS_ORIGIN_WHITELIST: ["richie.example.com"] # The domain on which Richie is hosted\n'})}),"\n",(0,s.jsx)(n.h2,{id:"allow-redirects",children:"Allow redirects"}),"\n",(0,s.jsxs)(n.p,{children:["When Richie sends the user to the OpenEdX instance for authentication, and wants OpenEdX to\nredirect the user back to Richie after a successful login or signup, it prefixes the path with\n",(0,s.jsx)(n.code,{children:"/richie"}),". Adding the following rule to your Nginx server (or equivalent) and replacing the\nrichie host by yours will allow this redirect to follow through to your Richie instance:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"rewrite ^/richie/(.*)$ https://richie.example.com/$1 permanent;\n"})}),"\n",(0,s.jsx)(n.h2,{id:"configure-authentication-delegation",children:"Configure authentication delegation"}),"\n",(0,s.jsxs)(n.p,{children:["Now, on your Richie instance, you need to configure the service to which Richie will delegate\nauthentication using the ",(0,s.jsx)(n.code,{children:"RICHIE_AUTHENTICATION_DELEGATION"})," setting:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'RICHIE_AUTHENTICATION_DELEGATION = {\n "BASE_URL": "https://lms.example.com",\n "BACKEND": "openedx-hawthorn",\n "PROFILE_URLS": {\n "dashboard": {\n "label": _("Dashboard"),\n "href": "{base_url:s}/dashboard",\n },\n },\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"The following should help you understand how to configure this setting:"}),"\n",(0,s.jsx)(n.h3,{id:"base_url",children:"BASE_URL"}),"\n",(0,s.jsx)(n.p,{children:"The base url on which the OpenEdX instance is hosted. This is used to construct the complete url\nof the login/signup pages to which the frontend application will send the user for authentication."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Type: string"}),"\n",(0,s.jsx)(n.li,{children:"Required: Yes"}),"\n",(0,s.jsxs)(n.li,{children:["Value: for example ",(0,s.jsx)(n.a,{href:"https://lms.example.com",children:"https://lms.example.com"})]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"backend",children:"BACKEND"}),"\n",(0,s.jsx)(n.p,{children:"The name of the ReactJS backend to use for the targeted LMS."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Type: string"}),"\n",(0,s.jsx)(n.li,{children:"Required: Yes"}),"\n",(0,s.jsxs)(n.li,{children:["Value: Richie ships with the following Javascript backends:","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"openedx-dogwood"}),": backend for OpenEdX versions equal to ",(0,s.jsx)(n.code,{children:"dogwood"})," or ",(0,s.jsx)(n.code,{children:"eucalyptus"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"openedx-hawthorn"}),": backend for OpenEdX versions equal to ",(0,s.jsx)(n.code,{children:"hawthorn"})," or higher"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"openedx-fonzie"}),": backend for OpenEdX via ",(0,s.jsx)(n.a,{href:"https://github.com/openfun/fonzie",children:"Fonzie"}),"\n(extra user info and JWT tokens)"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"base"}),": fake backend for development purposes"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"profile_urls",children:"PROFILE_URLS"}),"\n",(0,s.jsx)(n.p,{children:"Mapping definition of custom links presented to the logged-in user as a dropdown menu when he/she\nclicks on his/her username in Richie's page header."}),"\n",(0,s.jsx)(n.p,{children:"Links order will be respected to build the dropdown menu."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Type: dictionary"}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Required: No"}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Value: For example, to emulate the links proposed in OpenEdX, you can configure this setting\nas follows:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:' {\n "dashboard": {\n "label": _("Dashboard"),\n "href": "{base_url:s}/dashboard",\n },\n "profile": {\n "label": _("Profile"),\n "href": "{base_url:s}/u/(username)",\n },\n "account": {\n "label": _("Account"),\n "href": "{base_url:s}/account/settings",\n }\n }\n'})}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"base_url"})," variable is used as a Python format parameter and will be replaced by the value\nset for the above authentication delegation ",(0,s.jsx)(n.code,{children:"BASE_URL"})," setting."]}),"\n",(0,s.jsxs)(n.p,{children:["If you need to bind user data into a url, wrap the property between brackets. For example, the\nlink configured above for the profile page ",(0,s.jsx)(n.code,{children:"{base_url:s}/u/(username)"})," would point to\n",(0,s.jsx)(n.code,{children:"https://lms.example.com/u/johndoe"})," for a user carrying the username ",(0,s.jsx)(n.code,{children:"johndoe"}),"."]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,t.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},11151:(e,n,i)=>{i.d(n,{Z:()=>a,a:()=>r});var s=i(67294);const t={},o=s.createContext(t);function r(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/00936db6.fa95273e.js b/assets/js/00936db6.fa95273e.js new file mode 100644 index 0000000000..0056113a53 --- /dev/null +++ b/assets/js/00936db6.fa95273e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[64513],{7586:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>a,toc:()=>c});var s=i(85893),t=i(11151);const o={id:"displaying-connection-status",title:"Displaying OpenEdX connection status in Richie",sidebar_label:"Displaying connection status"},r=void 0,a={id:"displaying-connection-status",title:"Displaying OpenEdX connection status in Richie",description:"This guide explains how to configure Richie and OpenEdX to share the OpenEdX connection status",source:"@site/versioned_docs/version-2.8.1/displaying-connection-status.md",sourceDirName:".",slug:"/displaying-connection-status",permalink:"/docs/2.8.1/displaying-connection-status",draft:!1,unlisted:!1,tags:[],version:"2.8.1",lastUpdatedBy:"Mehdi Benadda",lastUpdatedAt:1655108611e3,frontMatter:{id:"displaying-connection-status",title:"Displaying OpenEdX connection status in Richie",sidebar_label:"Displaying connection status"}},l={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Allow redirects",id:"allow-redirects",level:2},{value:"Configure authentication delegation",id:"configure-authentication-delegation",level:2},{value:"BASE_URL",id:"base_url",level:3},{value:"BACKEND",id:"backend",level:3},{value:"PROFILE_URLS",id:"profile_urls",level:3}];function d(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,t.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:"This guide explains how to configure Richie and OpenEdX to share the OpenEdX connection status\nand display profile information for the logged-in user in Richie."}),"\n",(0,s.jsx)(n.p,{children:"In Richie, the only users that are actually authenticated on the DjangoCMS instance producing the\nsite, are editors and staff users. Your instructors and learners will not have user accounts on\nRichie, but authentication is delegated to a remote service that can be OpenEdX, KeyCloack, or\nyour own centralized identity management service."}),"\n",(0,s.jsx)(n.p,{children:"In the following, we will explain how to use OpenEdX as your authentication delegation service."}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsx)(n.p,{children:"Richie will need to make CORS requests to the OpenEdX instance. As a consequence, you need to\nactivate CORS requests on your OpenEdX instance:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'FEATURES = {\n ...\n "ENABLE_CORS_HEADERS": True,\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"Then, make sure the following settings are set as follows on your OpenEdX instance:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'CORS_ALLOW_CREDENTIALS = True\nCORS_ALLOW_INSECURE = False\nCORS_ORIGIN_ALLOW_ALL = False\nCORS_ORIGIN_WHITELIST: ["richie.example.com"] # The domain on which Richie is hosted\n'})}),"\n",(0,s.jsx)(n.h2,{id:"allow-redirects",children:"Allow redirects"}),"\n",(0,s.jsxs)(n.p,{children:["When Richie sends the user to the OpenEdX instance for authentication, and wants OpenEdX to\nredirect the user back to Richie after a successful login or signup, it prefixes the path with\n",(0,s.jsx)(n.code,{children:"/richie"}),". Adding the following rule to your Nginx server (or equivalent) and replacing the\nrichie host by yours will allow this redirect to follow through to your Richie instance:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"rewrite ^/richie/(.*)$ https://richie.example.com/$1 permanent;\n"})}),"\n",(0,s.jsx)(n.h2,{id:"configure-authentication-delegation",children:"Configure authentication delegation"}),"\n",(0,s.jsxs)(n.p,{children:["Now, on your Richie instance, you need to configure the service to which Richie will delegate\nauthentication using the ",(0,s.jsx)(n.code,{children:"RICHIE_AUTHENTICATION_DELEGATION"})," setting:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'RICHIE_AUTHENTICATION_DELEGATION = {\n "BASE_URL": "https://lms.example.com",\n "BACKEND": "openedx-hawthorn",\n "PROFILE_URLS": {\n "dashboard": {\n "label": _("Dashboard"),\n "href": "{base_url:s}/dashboard",\n },\n },\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"The following should help you understand how to configure this setting:"}),"\n",(0,s.jsx)(n.h3,{id:"base_url",children:"BASE_URL"}),"\n",(0,s.jsx)(n.p,{children:"The base url on which the OpenEdX instance is hosted. This is used to construct the complete url\nof the login/signup pages to which the frontend application will send the user for authentication."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Type: string"}),"\n",(0,s.jsx)(n.li,{children:"Required: Yes"}),"\n",(0,s.jsxs)(n.li,{children:["Value: for example ",(0,s.jsx)(n.a,{href:"https://lms.example.com",children:"https://lms.example.com"})]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"backend",children:"BACKEND"}),"\n",(0,s.jsx)(n.p,{children:"The name of the ReactJS backend to use for the targeted LMS."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Type: string"}),"\n",(0,s.jsx)(n.li,{children:"Required: Yes"}),"\n",(0,s.jsxs)(n.li,{children:["Value: Richie ships with the following Javascript backends:","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"openedx-dogwood"}),": backend for OpenEdX versions equal to ",(0,s.jsx)(n.code,{children:"dogwood"})," or ",(0,s.jsx)(n.code,{children:"eucalyptus"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"openedx-hawthorn"}),": backend for OpenEdX versions equal to ",(0,s.jsx)(n.code,{children:"hawthorn"})," or higher"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"openedx-fonzie"}),": backend for OpenEdX via ",(0,s.jsx)(n.a,{href:"https://github.com/openfun/fonzie",children:"Fonzie"}),"\n(extra user info and JWT tokens)"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"base"}),": fake backend for development purposes"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"profile_urls",children:"PROFILE_URLS"}),"\n",(0,s.jsx)(n.p,{children:"Mapping definition of custom links presented to the logged-in user as a dropdown menu when he/she\nclicks on his/her username in Richie's page header."}),"\n",(0,s.jsx)(n.p,{children:"Links order will be respected to build the dropdown menu."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Type: dictionary"}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Required: No"}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Value: For example, to emulate the links proposed in OpenEdX, you can configure this setting\nas follows:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:' {\n "dashboard": {\n "label": _("Dashboard"),\n "href": "{base_url:s}/dashboard",\n },\n "profile": {\n "label": _("Profile"),\n "href": "{base_url:s}/u/(username)",\n },\n "account": {\n "label": _("Account"),\n "href": "{base_url:s}/account/settings",\n }\n }\n'})}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"base_url"})," variable is used as a Python format parameter and will be replaced by the value\nset for the above authentication delegation ",(0,s.jsx)(n.code,{children:"BASE_URL"})," setting."]}),"\n",(0,s.jsxs)(n.p,{children:["If you need to bind user data into a url, wrap the property between brackets. For example, the\nlink configured above for the profile page ",(0,s.jsx)(n.code,{children:"{base_url:s}/u/(username)"})," would point to\n",(0,s.jsx)(n.code,{children:"https://lms.example.com/u/johndoe"})," for a user carrying the username ",(0,s.jsx)(n.code,{children:"johndoe"}),"."]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,t.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},11151:(e,n,i)=>{i.d(n,{Z:()=>a,a:()=>r});var s=i(67294);const t={},o=s.createContext(t);function r(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/00a73d6c.1fe4d188.js b/assets/js/00a73d6c.1fe4d188.js new file mode 100644 index 0000000000..41058d3343 --- /dev/null +++ b/assets/js/00a73d6c.1fe4d188.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[29964],{38184:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>t,metadata:()=>c,toc:()=>d});var i=s(85893),r=s(11151);const t={id:"synchronizing-course-runs",title:"Synchronizing course runs between Richie and OpenEdX",sidebar_label:"Synchronizing course runs"},o=void 0,c={id:"synchronizing-course-runs",title:"Synchronizing course runs between Richie and OpenEdX",description:"Richie can receive automatic course runs updates on a dedicated API endpoint.",source:"@site/versioned_docs/version-2.17.0/synchronizing-course-runs.md",sourceDirName:".",slug:"/synchronizing-course-runs",permalink:"/docs/2.17.0/synchronizing-course-runs",draft:!1,unlisted:!1,tags:[],version:"2.17.0",lastUpdatedBy:"jbpenrath",lastUpdatedAt:1666962873e3,frontMatter:{id:"synchronizing-course-runs",title:"Synchronizing course runs between Richie and OpenEdX",sidebar_label:"Synchronizing course runs"}},a={},d=[{value:"Configure a shared secret",id:"configure-a-shared-secret",level:2},{value:"Configure LMS backends",id:"configure-lms-backends",level:2},{value:"Make a synchronization query",id:"make-a-synchronization-query",level:2}];function u(e){const n={a:"a",code:"code",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.p,{children:"Richie can receive automatic course runs updates on a dedicated API endpoint."}),"\n",(0,i.jsx)(n.h2,{id:"configure-a-shared-secret",children:"Configure a shared secret"}),"\n",(0,i.jsxs)(n.p,{children:["In order to activate the course run synchronization API endpoint, you first need to configure the\n",(0,i.jsx)(n.code,{children:"RICHIE_COURSE_RUN_SYNC_SECRETS"})," setting with one or more secrets:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'RICHIE_COURSE_RUN_SYNC_SECRETS = ["SharedSecret", "OtherSharedSecret"]\n'})}),"\n",(0,i.jsx)(n.p,{children:"This setting collects several secrets in order to allow rotating them without any downtime. Any\nof the secrets listed in this setting can be used to sign your queries."}),"\n",(0,i.jsx)(n.p,{children:"Your secret should be shared with the LMS or distant system that needs to synchronize its course\nruns with the Richie instance. Richie will try the declared secrets one by one until it finds\none that matches the signature sent by the remote system."}),"\n",(0,i.jsx)(n.h2,{id:"configure-lms-backends",children:"Configure LMS backends"}),"\n",(0,i.jsxs)(n.p,{children:["You then need to configure the LMS handler via the ",(0,i.jsx)(n.code,{children:"RICHIE_LMS_BACKENDS"})," setting as explained\nin our ",(0,i.jsx)(n.a,{href:"lms-backends#configuring-the-lms-handler",children:"guide on configuring LMS backends"}),". This is\nrequired if you want Richie to create a new course run automatically and associate it with the\nright course when the resource link submitted to the course run synchronization API endpoint is\nunknown to Richie."]}),"\n",(0,i.jsxs)(n.p,{children:["Each course run can be set to react differently to a synchronization request, thanks to the\n",(0,i.jsx)(n.code,{children:"sync_mode"})," field. This field can be set to one of the following values:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"manual"}),": this course run is ignored by the course runs synchronization script. In this case,\nthe course run can only be edited manually using the DjangoCMS frontend editing."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"sync_to_draft"}),": only the draft version of this course run is synchronized. A manual\npublication is necessary for the update to be visible on the public site."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"sync_to_public"}),": the public version of this course run is updated by the synchronization\nscript. As a results, updates are directly visible on the public site without further\npublication by a staff user in Richie."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["A ",(0,i.jsx)(n.a,{href:"lms-backends#default_course_run_sync_mode",children:"DEFAULT_COURSE_RUN_SYNC_MODE parameter"})," in the\n",(0,i.jsx)(n.code,{children:"RICHIE_LMS_BACKENDS"})," setting, defines what default value is used for new course runs."]}),"\n",(0,i.jsx)(n.h2,{id:"make-a-synchronization-query",children:"Make a synchronization query"}),"\n",(0,i.jsxs)(n.p,{children:["You can refer to the ",(0,i.jsx)(n.a,{href:"api/course-run-synchronization-api",children:"documentation of the course run synchronization API"})," for details\non the query expected by this endpoint."]}),"\n",(0,i.jsxs)(n.p,{children:["We also share here our sample code to call this synchronization endpoint from OpenEdX. This code\nshould run on the ",(0,i.jsx)(n.code,{children:"post_publish"})," signal emitted by the OpenEdX ",(0,i.jsx)(n.code,{children:"cms"})," application each time a\ncourse run is modified and published."]}),"\n",(0,i.jsxs)(n.p,{children:["Or you can use the ",(0,i.jsx)(n.a,{href:"https://github.com/fccn/richie-openedx-sync",children:"Richie Open edX Synchronization"}),"\nwhich is based on the following code sample and also includes the enrollment count."]}),"\n",(0,i.jsxs)(n.p,{children:["Given a ",(0,i.jsx)(n.code,{children:"COURSE_HOOK"})," setting defined as follows in your OpenEdX instance:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'COURSE_HOOK = {\n "secret": "SharedSecret",\n "url": "https://richie.example.com/api/v1.0/course-runs-sync/",\n}\n'})}),"\n",(0,i.jsx)(n.p,{children:"The code for the synchronization function in OpenEdX could look like this:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'import hashlib\nimport hmac\nimport json\n\nfrom django.conf import settings\n\nfrom microsite_configuration import microsite\nimport requests\nfrom xmodule.modulestore.django import modulestore\n\n\ndef update_course(course_key, *args, **kwargs):\n """Synchronize an OpenEdX course, identified by its course key, with a Richie instance."""\n course = modulestore().get_course(course_key)\n edxapp_domain = microsite.get_value("site_domain", settings.LMS_BASE)\n\n data = {\n "resource_link": "https://{:s}/courses/{!s}/info".format(\n edxapp_domain, course_key\n ),\n "start": course.start and course.start.isoformat(),\n "end": course.end and course.end.isoformat(),\n "enrollment_start": course.enrollment_start and course.enrollment_start.isoformat(),\n "enrollment_end": course.enrollment_end and course.enrollment_end.isoformat(),\n "languages": [course.language or settings.LANGUAGE_CODE],\n }\n\n signature = hmac.new(\n setting.COURSE_HOOK["secret"].encode("utf-8"),\n msg=json.dumps(data).encode("utf-8"),\n digestmod=hashlib.sha256,\n ).hexdigest()\n\n response = requests.post(\n setting.COURSE_HOOK["url"],\n json=data,\n headers={"Authorization": "SIG-HMAC-SHA256 {:s}".format(signature)},\n )\n'})}),"\n",(0,i.jsx)(n.p,{children:"Thanks to the signal emitted in OpenEdX, this function can then be triggered each time a course\nis modified and published:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:"from django.dispatch import receiver\nfrom xmodule.modulestore.django import SignalHandler\n\n\n@receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')\ndef update_course_on_publish(sender, course_key, **kwargs):\n update_course(course_key)\n"})})]})}function h(e={}){const{wrapper:n}={...(0,r.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(u,{...e})}):u(e)}},11151:(e,n,s)=>{s.d(n,{Z:()=>c,a:()=>o});var i=s(67294);const r={},t=i.createContext(r);function o(e){const n=i.useContext(t);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),i.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/00a73d6c.dbe2ecca.js b/assets/js/00a73d6c.dbe2ecca.js deleted file mode 100644 index 1b3eac4430..0000000000 --- a/assets/js/00a73d6c.dbe2ecca.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[29964],{38184:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var i=s(85893),t=s(11151);const r={id:"synchronizing-course-runs",title:"Synchronizing course runs between Richie and OpenEdX",sidebar_label:"Synchronizing course runs"},o=void 0,c={id:"synchronizing-course-runs",title:"Synchronizing course runs between Richie and OpenEdX",description:"Richie can receive automatic course runs updates on a dedicated API endpoint.",source:"@site/versioned_docs/version-2.17.0/synchronizing-course-runs.md",sourceDirName:".",slug:"/synchronizing-course-runs",permalink:"/docs/2.17.0/synchronizing-course-runs",draft:!1,unlisted:!1,tags:[],version:"2.17.0",lastUpdatedBy:"jbpenrath",lastUpdatedAt:1666962873,formattedLastUpdatedAt:"Oct 28, 2022",frontMatter:{id:"synchronizing-course-runs",title:"Synchronizing course runs between Richie and OpenEdX",sidebar_label:"Synchronizing course runs"}},a={},d=[{value:"Configure a shared secret",id:"configure-a-shared-secret",level:2},{value:"Configure LMS backends",id:"configure-lms-backends",level:2},{value:"Make a synchronization query",id:"make-a-synchronization-query",level:2}];function u(e){const n={a:"a",code:"code",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,t.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.p,{children:"Richie can receive automatic course runs updates on a dedicated API endpoint."}),"\n",(0,i.jsx)(n.h2,{id:"configure-a-shared-secret",children:"Configure a shared secret"}),"\n",(0,i.jsxs)(n.p,{children:["In order to activate the course run synchronization API endpoint, you first need to configure the\n",(0,i.jsx)(n.code,{children:"RICHIE_COURSE_RUN_SYNC_SECRETS"})," setting with one or more secrets:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'RICHIE_COURSE_RUN_SYNC_SECRETS = ["SharedSecret", "OtherSharedSecret"]\n'})}),"\n",(0,i.jsx)(n.p,{children:"This setting collects several secrets in order to allow rotating them without any downtime. Any\nof the secrets listed in this setting can be used to sign your queries."}),"\n",(0,i.jsx)(n.p,{children:"Your secret should be shared with the LMS or distant system that needs to synchronize its course\nruns with the Richie instance. Richie will try the declared secrets one by one until it finds\none that matches the signature sent by the remote system."}),"\n",(0,i.jsx)(n.h2,{id:"configure-lms-backends",children:"Configure LMS backends"}),"\n",(0,i.jsxs)(n.p,{children:["You then need to configure the LMS handler via the ",(0,i.jsx)(n.code,{children:"RICHIE_LMS_BACKENDS"})," setting as explained\nin our ",(0,i.jsx)(n.a,{href:"lms-backends#configuring-the-lms-handler",children:"guide on configuring LMS backends"}),". This is\nrequired if you want Richie to create a new course run automatically and associate it with the\nright course when the resource link submitted to the course run synchronization API endpoint is\nunknown to Richie."]}),"\n",(0,i.jsxs)(n.p,{children:["Each course run can be set to react differently to a synchronization request, thanks to the\n",(0,i.jsx)(n.code,{children:"sync_mode"})," field. This field can be set to one of the following values:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"manual"}),": this course run is ignored by the course runs synchronization script. In this case,\nthe course run can only be edited manually using the DjangoCMS frontend editing."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"sync_to_draft"}),": only the draft version of this course run is synchronized. A manual\npublication is necessary for the update to be visible on the public site."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"sync_to_public"}),": the public version of this course run is updated by the synchronization\nscript. As a results, updates are directly visible on the public site without further\npublication by a staff user in Richie."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["A ",(0,i.jsx)(n.a,{href:"lms-backends#default_course_run_sync_mode",children:"DEFAULT_COURSE_RUN_SYNC_MODE parameter"})," in the\n",(0,i.jsx)(n.code,{children:"RICHIE_LMS_BACKENDS"})," setting, defines what default value is used for new course runs."]}),"\n",(0,i.jsx)(n.h2,{id:"make-a-synchronization-query",children:"Make a synchronization query"}),"\n",(0,i.jsxs)(n.p,{children:["You can refer to the ",(0,i.jsx)(n.a,{href:"api/course-run-synchronization-api",children:"documentation of the course run synchronization API"})," for details\non the query expected by this endpoint."]}),"\n",(0,i.jsxs)(n.p,{children:["We also share here our sample code to call this synchronization endpoint from OpenEdX. This code\nshould run on the ",(0,i.jsx)(n.code,{children:"post_publish"})," signal emitted by the OpenEdX ",(0,i.jsx)(n.code,{children:"cms"})," application each time a\ncourse run is modified and published."]}),"\n",(0,i.jsxs)(n.p,{children:["Or you can use the ",(0,i.jsx)(n.a,{href:"https://github.com/fccn/richie-openedx-sync",children:"Richie Open edX Synchronization"}),"\nwhich is based on the following code sample and also includes the enrollment count."]}),"\n",(0,i.jsxs)(n.p,{children:["Given a ",(0,i.jsx)(n.code,{children:"COURSE_HOOK"})," setting defined as follows in your OpenEdX instance:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'COURSE_HOOK = {\n "secret": "SharedSecret",\n "url": "https://richie.example.com/api/v1.0/course-runs-sync/",\n}\n'})}),"\n",(0,i.jsx)(n.p,{children:"The code for the synchronization function in OpenEdX could look like this:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'import hashlib\nimport hmac\nimport json\n\nfrom django.conf import settings\n\nfrom microsite_configuration import microsite\nimport requests\nfrom xmodule.modulestore.django import modulestore\n\n\ndef update_course(course_key, *args, **kwargs):\n """Synchronize an OpenEdX course, identified by its course key, with a Richie instance."""\n course = modulestore().get_course(course_key)\n edxapp_domain = microsite.get_value("site_domain", settings.LMS_BASE)\n\n data = {\n "resource_link": "https://{:s}/courses/{!s}/info".format(\n edxapp_domain, course_key\n ),\n "start": course.start and course.start.isoformat(),\n "end": course.end and course.end.isoformat(),\n "enrollment_start": course.enrollment_start and course.enrollment_start.isoformat(),\n "enrollment_end": course.enrollment_end and course.enrollment_end.isoformat(),\n "languages": [course.language or settings.LANGUAGE_CODE],\n }\n\n signature = hmac.new(\n setting.COURSE_HOOK["secret"].encode("utf-8"),\n msg=json.dumps(data).encode("utf-8"),\n digestmod=hashlib.sha256,\n ).hexdigest()\n\n response = requests.post(\n setting.COURSE_HOOK["url"],\n json=data,\n headers={"Authorization": "SIG-HMAC-SHA256 {:s}".format(signature)},\n )\n'})}),"\n",(0,i.jsx)(n.p,{children:"Thanks to the signal emitted in OpenEdX, this function can then be triggered each time a course\nis modified and published:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:"from django.dispatch import receiver\nfrom xmodule.modulestore.django import SignalHandler\n\n\n@receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')\ndef update_course_on_publish(sender, course_key, **kwargs):\n update_course(course_key)\n"})})]})}function h(e={}){const{wrapper:n}={...(0,t.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(u,{...e})}):u(e)}},11151:(e,n,s)=>{s.d(n,{Z:()=>c,a:()=>o});var i=s(67294);const t={},r=i.createContext(t);function o(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0282d9da.39cf5b70.js b/assets/js/0282d9da.39cf5b70.js new file mode 100644 index 0000000000..44aa8aa337 --- /dev/null +++ b/assets/js/0282d9da.39cf5b70.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[87115],{37557:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>a,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var n=t(85893),i=t(11151);const o={id:"css-guidelines",title:"CSS Guidelines",sidebar_label:"CSS Guidelines"},r=void 0,l={id:"css-guidelines",title:"CSS Guidelines",description:"The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.",source:"@site/versioned_docs/version-2.24.0/css-guidelines.md",sourceDirName:".",slug:"/css-guidelines",permalink:"/docs/2.24.0/css-guidelines",draft:!1,unlisted:!1,tags:[],version:"2.24.0",lastUpdatedBy:"jbpenrath",lastUpdatedAt:1693581273e3,frontMatter:{id:"css-guidelines",title:"CSS Guidelines",sidebar_label:"CSS Guidelines"},sidebar:"docs",previous:{title:"Accessibility testing",permalink:"/docs/2.24.0/accessibility-testing"}},a={},c=[{value:"File structuration",id:"file-structuration",level:2},{value:"Code structuration",id:"code-structuration",level:2},{value:"Quick pointers",id:"quick-pointers",level:2}];function d(e){const s={a:"a",code:"code",em:"em",h2:"h2",li:"li",p:"p",strong:"strong",ul:"ul",...(0,i.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.p,{children:"The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly."}),"\n",(0,n.jsx)(s.p,{children:"Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations."}),"\n",(0,n.jsx)(s.h2,{id:"file-structuration",children:"File structuration"}),"\n",(0,n.jsx)(s.p,{children:"Rules should be placed where their purpose is most apparent, and where they are easiest to find."}),"\n",(0,n.jsxs)(s.p,{children:["Generally, this means CSS rules should live as close as possible to the place they are used. For example, the selectors and rules that define the look for a component should live in a ",(0,n.jsx)(s.code,{children:".scss"})," file in the same folder as the JS file for this component. This goes for templates too. Such files can only contain rules that are ",(0,n.jsx)(s.strong,{children:"specific to this component/template and this one only"})]}),"\n",(0,n.jsxs)(s.p,{children:["Only general base rules, utility rules, site layout rules as well as our custom variables should live in the central ",(0,n.jsx)(s.code,{children:"app/static/scss"})," folder."]}),"\n",(0,n.jsx)(s.h2,{id:"code-structuration",children:"Code structuration"}),"\n",(0,n.jsx)(s.p,{children:"In order to understand what classes are about at a glance and avoid collisions, naming conventions must be enforced for classes."}),"\n",(0,n.jsxs)(s.p,{children:["Following the ",(0,n.jsx)(s.a,{href:"http://getbem.com/introduction/",children:"BEM naming convention"}),", we will write our classes as follows :"]}),"\n",(0,n.jsxs)(s.p,{children:[".block ","\n.block__element ","\n.block--modifier "]}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:".block"})," represents the higher level of an abstraction or component."]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:".block__element"})," represents a descendent of .block that helps form .block as a whole."]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:".block--modifier"})," represents a different state or version of .block."]}),"\n"]}),"\n",(0,n.jsxs)(s.p,{children:["We use double hyphens and double underscores as delimiters so that names themselves can be hyphen-delimited (e.g. ",(0,n.jsx)(s.code,{children:".site-search__field--full"}),")."]}),"\n",(0,n.jsx)(s.p,{children:"Yes, this notation is ugly. However, it allows our classes to express what they are doing. Both our CSS and our markup become more meaningful. It allows us to easily see what classes are related to others, and how they are related, when we look at the markup."}),"\n",(0,n.jsx)(s.h2,{id:"quick-pointers",children:"Quick pointers"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:["In general, ",(0,n.jsx)(s.strong,{children:"do not use IDs"}),". ",(0,n.jsx)(s.em,{children:"They can cause specificity wars and are not supposed to be reusable, and are therefore not very useful."})]}),"\n",(0,n.jsxs)(s.li,{children:["Do not nest selectors unnecessarily. ",(0,n.jsx)(s.em,{children:"It will increase specificity and affect where else you can use your styles."})]}),"\n",(0,n.jsxs)(s.li,{children:["Do not qualify selectors unnecessarily. ",(0,n.jsx)(s.em,{children:"It will impact the number of different elements you can apply styles to."})]}),"\n",(0,n.jsxs)(s.li,{children:["Comment profusely, ",(0,n.jsx)(s.em,{children:"whenever you think the CSS is getting complex or it would not be easy to understand its intent."})]}),"\n",(0,n.jsxs)(s.li,{children:["Use !important proactively. ",(0,n.jsx)(s.em,{children:"!important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively."})]}),"\n"]}),"\n",(0,n.jsxs)(s.p,{children:["(Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. ",(0,n.jsx)(s.code,{children:"div > #example"})," is A LOT more efficient than ",(0,n.jsx)(s.code,{children:"#example > div"})," although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See ",(0,n.jsx)(s.a,{href:"http://csswizardry.com/2011/09/writing-efficient-css-selectors/",children:"CSS Wizardry"})," for more details."]})]})}function u(e={}){const{wrapper:s}={...(0,i.a)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},11151:(e,s,t)=>{t.d(s,{Z:()=>l,a:()=>r});var n=t(67294);const i={},o=n.createContext(i);function r(e){const s=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),n.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0282d9da.8043f81c.js b/assets/js/0282d9da.8043f81c.js deleted file mode 100644 index 87675f1603..0000000000 --- a/assets/js/0282d9da.8043f81c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[87115],{37557:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>a,contentTitle:()=>r,default:()=>u,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var n=t(85893),o=t(11151);const i={id:"css-guidelines",title:"CSS Guidelines",sidebar_label:"CSS Guidelines"},r=void 0,l={id:"css-guidelines",title:"CSS Guidelines",description:"The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.",source:"@site/versioned_docs/version-2.24.0/css-guidelines.md",sourceDirName:".",slug:"/css-guidelines",permalink:"/docs/2.24.0/css-guidelines",draft:!1,unlisted:!1,tags:[],version:"2.24.0",lastUpdatedBy:"jbpenrath",lastUpdatedAt:1693581273,formattedLastUpdatedAt:"Sep 1, 2023",frontMatter:{id:"css-guidelines",title:"CSS Guidelines",sidebar_label:"CSS Guidelines"},sidebar:"docs",previous:{title:"Accessibility testing",permalink:"/docs/2.24.0/accessibility-testing"}},a={},c=[{value:"File structuration",id:"file-structuration",level:2},{value:"Code structuration",id:"code-structuration",level:2},{value:"Quick pointers",id:"quick-pointers",level:2}];function d(e){const s={a:"a",code:"code",em:"em",h2:"h2",li:"li",p:"p",strong:"strong",ul:"ul",...(0,o.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.p,{children:"The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly."}),"\n",(0,n.jsx)(s.p,{children:"Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations."}),"\n",(0,n.jsx)(s.h2,{id:"file-structuration",children:"File structuration"}),"\n",(0,n.jsx)(s.p,{children:"Rules should be placed where their purpose is most apparent, and where they are easiest to find."}),"\n",(0,n.jsxs)(s.p,{children:["Generally, this means CSS rules should live as close as possible to the place they are used. For example, the selectors and rules that define the look for a component should live in a ",(0,n.jsx)(s.code,{children:".scss"})," file in the same folder as the JS file for this component. This goes for templates too. Such files can only contain rules that are ",(0,n.jsx)(s.strong,{children:"specific to this component/template and this one only"})]}),"\n",(0,n.jsxs)(s.p,{children:["Only general base rules, utility rules, site layout rules as well as our custom variables should live in the central ",(0,n.jsx)(s.code,{children:"app/static/scss"})," folder."]}),"\n",(0,n.jsx)(s.h2,{id:"code-structuration",children:"Code structuration"}),"\n",(0,n.jsx)(s.p,{children:"In order to understand what classes are about at a glance and avoid collisions, naming conventions must be enforced for classes."}),"\n",(0,n.jsxs)(s.p,{children:["Following the ",(0,n.jsx)(s.a,{href:"http://getbem.com/introduction/",children:"BEM naming convention"}),", we will write our classes as follows :"]}),"\n",(0,n.jsxs)(s.p,{children:[".block ","\n.block__element ","\n.block--modifier "]}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:".block"})," represents the higher level of an abstraction or component."]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:".block__element"})," represents a descendent of .block that helps form .block as a whole."]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:".block--modifier"})," represents a different state or version of .block."]}),"\n"]}),"\n",(0,n.jsxs)(s.p,{children:["We use double hyphens and double underscores as delimiters so that names themselves can be hyphen-delimited (e.g. ",(0,n.jsx)(s.code,{children:".site-search__field--full"}),")."]}),"\n",(0,n.jsx)(s.p,{children:"Yes, this notation is ugly. However, it allows our classes to express what they are doing. Both our CSS and our markup become more meaningful. It allows us to easily see what classes are related to others, and how they are related, when we look at the markup."}),"\n",(0,n.jsx)(s.h2,{id:"quick-pointers",children:"Quick pointers"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:["In general, ",(0,n.jsx)(s.strong,{children:"do not use IDs"}),". ",(0,n.jsx)(s.em,{children:"They can cause specificity wars and are not supposed to be reusable, and are therefore not very useful."})]}),"\n",(0,n.jsxs)(s.li,{children:["Do not nest selectors unnecessarily. ",(0,n.jsx)(s.em,{children:"It will increase specificity and affect where else you can use your styles."})]}),"\n",(0,n.jsxs)(s.li,{children:["Do not qualify selectors unnecessarily. ",(0,n.jsx)(s.em,{children:"It will impact the number of different elements you can apply styles to."})]}),"\n",(0,n.jsxs)(s.li,{children:["Comment profusely, ",(0,n.jsx)(s.em,{children:"whenever you think the CSS is getting complex or it would not be easy to understand its intent."})]}),"\n",(0,n.jsxs)(s.li,{children:["Use !important proactively. ",(0,n.jsx)(s.em,{children:"!important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively."})]}),"\n"]}),"\n",(0,n.jsxs)(s.p,{children:["(Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. ",(0,n.jsx)(s.code,{children:"div > #example"})," is A LOT more efficient than ",(0,n.jsx)(s.code,{children:"#example > div"})," although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See ",(0,n.jsx)(s.a,{href:"http://csswizardry.com/2011/09/writing-efficient-css-selectors/",children:"CSS Wizardry"})," for more details."]})]})}function u(e={}){const{wrapper:s}={...(0,o.a)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},11151:(e,s,t)=>{t.d(s,{Z:()=>l,a:()=>r});var n=t(67294);const o={},i=n.createContext(o);function r(e){const s=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),n.createElement(i.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2f1db623.d8badd5c.js b/assets/js/0293ad88.eb8399b8.js similarity index 56% rename from assets/js/2f1db623.d8badd5c.js rename to assets/js/0293ad88.eb8399b8.js index 5d67c231a5..a9eacddfc0 100644 --- a/assets/js/2f1db623.d8badd5c.js +++ b/assets/js/0293ad88.eb8399b8.js @@ -1 +1 @@ -"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[98842],{21804:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>h,frontMatter:()=>o,metadata:()=>t,toc:()=>l});var i=s(85893),r=s(11151);const o={id:"lms-backends",title:"Configuring LMS Backends",sidebar_label:"LMS Backends"},c=void 0,t={id:"lms-backends",title:"Configuring LMS Backends",description:"Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless",source:"@site/versioned_docs/version-2.12.0/lms-backends.md",sourceDirName:".",slug:"/lms-backends",permalink:"/docs/2.12.0/lms-backends",draft:!1,unlisted:!1,tags:[],version:"2.12.0",lastUpdatedBy:"Mehdi Benadda",lastUpdatedAt:1655108611,formattedLastUpdatedAt:"Jun 13, 2022",frontMatter:{id:"lms-backends",title:"Configuring LMS Backends",sidebar_label:"LMS Backends"}},d={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Configuring the LMS handler",id:"configuring-the-lms-handler",level:2},{value:"BASE_URL",id:"base_url",level:3},{value:"BACKEND",id:"backend",level:3},{value:"COURSE_REGEX",id:"course_regex",level:3},{value:"JS_BACKEND",id:"js_backend",level:3},{value:"JS_COURSE_REGEX",id:"js_course_regex",level:3},{value:"DEFAULT_COURSE_RUN_SYNC_MODE",id:"default_course_run_sync_mode",level:3},{value:"COURSE_RUN_SYNC_NO_UPDATE_FIELDS",id:"course_run_sync_no_update_fields",level:3},{value:"Technical support",id:"technical-support",level:2}];function a(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.p,{children:"Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless\nexperience between browsing the course catalog on Richie, enrolling to a course and following the\ncourse itself on the LMS."}),"\n",(0,i.jsx)(n.p,{children:"It is possible to do the same with Moodle or any other LMS exposing an enrollment API, at the\ncost of writing a custom LMS handler backend."}),"\n",(0,i.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsxs)(n.p,{children:["This connection requires that Richie and OpenEdX be hosted on sibling domains i.e. domains that\nare both subdomains of the same root domain, e.g. ",(0,i.jsx)(n.code,{children:"richie.example.com"})," and ",(0,i.jsx)(n.code,{children:"lms.example.com"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"OpenEdX will need to generate a CORS CSRF Cookie and this cookie is flagged as secure, which\nimplies that we are not able to use it without SSL connections."}),"\n",(0,i.jsx)(n.p,{children:"As a consequence, you need to configure your OpenEdX instance as follows:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'FEATURES = {\n ...\n "ENABLE_CORS_HEADERS": True,\n "ENABLE_CROSS_DOMAIN_CSRF_COOKIE": True,\n}\n\nCORS_ALLOW_CREDENTIALS = True\nCORS_ALLOW_INSECURE = False\nCORS_ORIGIN_WHITELIST: ["richie.example.com"] # The domain on which Richie is hosted\n\nCROSS_DOMAIN_CSRF_COOKIE_DOMAIN = ".example.com" # The parent domain shared by Richie and OpenEdX\nCROSS_DOMAIN_CSRF_COOKIE_NAME: "edx_csrf_token"\nSESSION_COOKIE_NAME: "edx_session"\n'})}),"\n",(0,i.jsx)(n.h2,{id:"configuring-the-lms-handler",children:"Configuring the LMS handler"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"LMSHandler"})," utility acts as a proxy that routes queries to the correct LMS backend API,\nbased on a regex match on the URL of the course. It is configured via the ",(0,i.jsx)(n.code,{children:"RICHIE_LMS_BACKENDS"}),"\nsetting. As an example, here is how it would be configured to connect to an Ironwood OpenEdX\ninstance hosted on ",(0,i.jsx)(n.code,{children:"https://lms.example.com"}),":"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'RICHIE_LMS_BACKENDS=[\n {\n "BASE_URL": "https://lms.example.com",\n # Django\n "BACKEND": "richie.apps.courses.lms.edx.EdXLMSBackend",\n "COURSE_REGEX": r"^https://lms\\.example\\.com/courses/(?P.*)/course/?$",\n # ReactJS\n "JS_BACKEND": "openedx-hawthorn",\n "JS_COURSE_REGEX": r"^https://lms\\.example\\.com/courses/(.*)/course/?$",\n # Course runs synchronization\n "COURSE_RUN_SYNC_NO_UPDATE_FIELDS": [],\n "DEFAULT_COURSE_RUN_SYNC_MODE": "sync_to_public",\n },\n]\n'})}),"\n",(0,i.jsx)(n.p,{children:"The following should help you understand how to configure this setting:"}),"\n",(0,i.jsx)(n.h3,{id:"base_url",children:"BASE_URL"}),"\n",(0,i.jsx)(n.p,{children:"The base url on which the OpenEdX instance is hosted. This is used to construct the complete url\nof the API endpoint on which the enrollment request is made by Richie's frontend application."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type: string"}),"\n",(0,i.jsx)(n.li,{children:"Required: Yes"}),"\n",(0,i.jsxs)(n.li,{children:["Value: for example ",(0,i.jsx)(n.a,{href:"https://lms.example.com",children:"https://lms.example.com"})]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"backend",children:"BACKEND"}),"\n",(0,i.jsx)(n.p,{children:"The path to a Python class serving as LMS backend for the targeted LMS."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type: string"}),"\n",(0,i.jsx)(n.li,{children:"Required: Yes"}),"\n",(0,i.jsxs)(n.li,{children:["Value: Richie ships with the following Python backends (custom backends can be written to fit\nanother specific LMS):","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"richie.apps.courses.lms.edx.EdXLMSBackend"}),": backend for OpenEdX"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"richie.apps.courses.lms.base.BaseLMSBackend"}),": fake backend for development purposes"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"course_regex",children:"COURSE_REGEX"}),"\n",(0,i.jsxs)(n.p,{children:["A Python regex that should match the course syllabus urls of the targeted LMS and return a\n",(0,i.jsx)(n.code,{children:"course_id"})," named group on the id of the course extracted from these urls."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type: string"}),"\n",(0,i.jsx)(n.li,{children:"Required: Yes"}),"\n",(0,i.jsxs)(n.li,{children:["Value: for example ",(0,i.jsx)(n.code,{children:"^.*/courses/(?P.*)/course/?$"})]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"js_backend",children:"JS_BACKEND"}),"\n",(0,i.jsx)(n.p,{children:"The name of the ReactJS backend to use for the targeted LMS."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type: string"}),"\n",(0,i.jsx)(n.li,{children:"Required: Yes"}),"\n",(0,i.jsxs)(n.li,{children:["Value: Richie ships with the following Javascript backends (custom backends can be written to\nfit another specific LMS):","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"openedx-dogwood"}),": backend for OpenEdX versions equal to ",(0,i.jsx)(n.code,{children:"dogwood"})," or ",(0,i.jsx)(n.code,{children:"eucalyptus"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"openedx-hawthorn"}),": backend for OpenEdX versions equal to ",(0,i.jsx)(n.code,{children:"hawthorn"})," or higher"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"openedx-fonzie"}),": backend for OpenEdX via ",(0,i.jsx)(n.a,{href:"https://github.com/openfun/fonzie",children:"Fonzie"}),"\n(extra user info and JWT tokens)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"base"}),": fake backend for development purposes"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"js_course_regex",children:"JS_COURSE_REGEX"}),"\n",(0,i.jsx)(n.p,{children:"A Javascript regex that should match the course syllabus urls of the targeted LMS and return an\nunnamed group on the id of the course extracted from these urls."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type: string"}),"\n",(0,i.jsx)(n.li,{children:"Required: Yes"}),"\n",(0,i.jsxs)(n.li,{children:["Value: for example ",(0,i.jsx)(n.code,{children:"^.*/courses/(.*)/course/?$"})]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"default_course_run_sync_mode",children:"DEFAULT_COURSE_RUN_SYNC_MODE"}),"\n",(0,i.jsxs)(n.p,{children:["When a course run is created, this setting is used to set the value of the ",(0,i.jsx)(n.code,{children:"sync_mode"})," field.\nThis value defines how the course runs synchronization script will impact this course run after\ncreation."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type: enum(string)"}),"\n",(0,i.jsx)(n.li,{children:"Required: No"}),"\n",(0,i.jsxs)(n.li,{children:["Value: possible values are ",(0,i.jsx)(n.code,{children:"manual"}),", ",(0,i.jsx)(n.code,{children:"sync_to_draft"})," and ",(0,i.jsx)(n.code,{children:"sync_to_public"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"manual"}),": this course run is ignored by the course runs synchronization script"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"sync_to_draft"}),": only the draft version of this course run is synchronized. A manual\npublication is necessary for the update to be visible on the public site."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"sync_to_public"}),": the public version of this course run is updated by the synchronization\nscript. As a results, updates are directly visible on the public site without further\npublication by a staff user in Richie."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"course_run_sync_no_update_fields",children:"COURSE_RUN_SYNC_NO_UPDATE_FIELDS"}),"\n",(0,i.jsx)(n.p,{children:"A list of fields that must only be set the first time a course run is synchronized. During this\nfirst synchronization, a new course run is created in Richie and all fields sent to the API\nendpoint via the payload are set on the object. For subsequent synchronization calls, the fields\nlisted in this setting are ignored and not synchronized. This can be used to allow modifying some\nfields manually in Richie regardless of what OpenEdX sends after an initial value is set."}),"\n",(0,i.jsxs)(n.p,{children:["Note that this setting is only effective for course runs with the ",(0,i.jsx)(n.code,{children:"sync_mode"})," field set to a\nvalue other then ",(0,i.jsx)(n.code,{children:"manual"}),"."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type: enum(string)"}),"\n",(0,i.jsx)(n.li,{children:"Required: No"}),"\n",(0,i.jsx)(n.li,{children:'Value: for example ["languages"]'}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"technical-support",children:"Technical support"}),"\n",(0,i.jsxs)(n.p,{children:["If you encounter an issue with this documentation or the backends included in Richie, please\n",(0,i.jsx)(n.a,{href:"https://github.com/openfun/richie/issues",children:"open an issue on our repository"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["If you need a custom backend, you can ",(0,i.jsx)(n.a,{href:"https://github.com/openfun/richie/pulls",children:"submit a PR"})," or\n",(0,i.jsx)(n.a,{href:"https://github.com/openfun/richie/issues",children:"open an issue"})," and we will consider adding it."]})]})}function h(e={}){const{wrapper:n}={...(0,r.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},11151:(e,n,s)=>{s.d(n,{Z:()=>t,a:()=>c});var i=s(67294);const r={},o=i.createContext(r);function c(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[9831],{29454:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>c,default:()=>h,frontMatter:()=>o,metadata:()=>t,toc:()=>d});var i=s(85893),r=s(11151);const o={id:"lms-backends",title:"Configuring LMS Backends",sidebar_label:"LMS Backends"},c=void 0,t={id:"lms-backends",title:"Configuring LMS Backends",description:"Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless",source:"@site/../docs/lms-backends.md",sourceDirName:".",slug:"/lms-backends",permalink:"/docs/next/lms-backends",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"jbpenrath",lastUpdatedAt:1652968488e3,frontMatter:{id:"lms-backends",title:"Configuring LMS Backends",sidebar_label:"LMS Backends"}},l={},d=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Configuring the LMS handler",id:"configuring-the-lms-handler",level:2},{value:"BASE_URL",id:"base_url",level:3},{value:"BACKEND",id:"backend",level:3},{value:"COURSE_REGEX",id:"course_regex",level:3},{value:"JS_BACKEND",id:"js_backend",level:3},{value:"JS_COURSE_REGEX",id:"js_course_regex",level:3},{value:"DEFAULT_COURSE_RUN_SYNC_MODE",id:"default_course_run_sync_mode",level:3},{value:"COURSE_RUN_SYNC_NO_UPDATE_FIELDS",id:"course_run_sync_no_update_fields",level:3},{value:"Technical support",id:"technical-support",level:2}];function a(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.p,{children:"Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless\nexperience between browsing the course catalog on Richie, enrolling to a course and following the\ncourse itself on the LMS."}),"\n",(0,i.jsx)(n.p,{children:"It is possible to do the same with Moodle or any other LMS exposing an enrollment API, at the\ncost of writing a custom LMS handler backend."}),"\n",(0,i.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsxs)(n.p,{children:["This connection requires that Richie and OpenEdX be hosted on sibling domains i.e. domains that\nare both subdomains of the same root domain, e.g. ",(0,i.jsx)(n.code,{children:"richie.example.com"})," and ",(0,i.jsx)(n.code,{children:"lms.example.com"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"OpenEdX will need to generate a CORS CSRF Cookie and this cookie is flagged as secure, which\nimplies that we are not able to use it without SSL connections."}),"\n",(0,i.jsx)(n.p,{children:"As a consequence, you need to configure your OpenEdX instance as follows:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'FEATURES = {\n ...\n "ENABLE_CORS_HEADERS": True,\n "ENABLE_CROSS_DOMAIN_CSRF_COOKIE": True,\n}\n\nCORS_ALLOW_CREDENTIALS = True\nCORS_ALLOW_INSECURE = False\nCORS_ORIGIN_WHITELIST: ["richie.example.com"] # The domain on which Richie is hosted\n\nCROSS_DOMAIN_CSRF_COOKIE_DOMAIN = ".example.com" # The parent domain shared by Richie and OpenEdX\nCROSS_DOMAIN_CSRF_COOKIE_NAME: "edx_csrf_token"\nSESSION_COOKIE_NAME: "edx_session"\n'})}),"\n",(0,i.jsx)(n.h2,{id:"configuring-the-lms-handler",children:"Configuring the LMS handler"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"LMSHandler"})," utility acts as a proxy that routes queries to the correct LMS backend API,\nbased on a regex match on the URL of the course. It is configured via the ",(0,i.jsx)(n.code,{children:"RICHIE_LMS_BACKENDS"}),"\nsetting. As an example, here is how it would be configured to connect to an Ironwood OpenEdX\ninstance hosted on ",(0,i.jsx)(n.code,{children:"https://lms.example.com"}),":"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'RICHIE_LMS_BACKENDS=[\n {\n "BASE_URL": "https://lms.example.com",\n # Django\n "BACKEND": "richie.apps.courses.lms.edx.EdXLMSBackend",\n "COURSE_REGEX": r"^https://lms\\.example\\.com/courses/(?P.*)/course/?$",\n # ReactJS\n "JS_BACKEND": "openedx-hawthorn",\n "JS_COURSE_REGEX": r"^https://lms\\.example\\.com/courses/(.*)/course/?$",\n # Course runs synchronization\n "COURSE_RUN_SYNC_NO_UPDATE_FIELDS": [],\n "DEFAULT_COURSE_RUN_SYNC_MODE": "sync_to_public",\n },\n]\n'})}),"\n",(0,i.jsx)(n.p,{children:"The following should help you understand how to configure this setting:"}),"\n",(0,i.jsx)(n.h3,{id:"base_url",children:"BASE_URL"}),"\n",(0,i.jsx)(n.p,{children:"The base url on which the OpenEdX instance is hosted. This is used to construct the complete url\nof the API endpoint on which the enrollment request is made by Richie's frontend application."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type: string"}),"\n",(0,i.jsx)(n.li,{children:"Required: Yes"}),"\n",(0,i.jsxs)(n.li,{children:["Value: for example ",(0,i.jsx)(n.a,{href:"https://lms.example.com",children:"https://lms.example.com"})]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"backend",children:"BACKEND"}),"\n",(0,i.jsx)(n.p,{children:"The path to a Python class serving as LMS backend for the targeted LMS."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type: string"}),"\n",(0,i.jsx)(n.li,{children:"Required: Yes"}),"\n",(0,i.jsxs)(n.li,{children:["Value: Richie ships with the following Python backends (custom backends can be written to fit\nanother specific LMS):","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"richie.apps.courses.lms.edx.EdXLMSBackend"}),": backend for OpenEdX"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"richie.apps.courses.lms.base.BaseLMSBackend"}),": fake backend for development purposes"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"course_regex",children:"COURSE_REGEX"}),"\n",(0,i.jsxs)(n.p,{children:["A Python regex that should match the course syllabus urls of the targeted LMS and return a\n",(0,i.jsx)(n.code,{children:"course_id"})," named group on the id of the course extracted from these urls."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type: string"}),"\n",(0,i.jsx)(n.li,{children:"Required: Yes"}),"\n",(0,i.jsxs)(n.li,{children:["Value: for example ",(0,i.jsx)(n.code,{children:"^.*/courses/(?P.*)/course/?$"})]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"js_backend",children:"JS_BACKEND"}),"\n",(0,i.jsx)(n.p,{children:"The name of the ReactJS backend to use for the targeted LMS."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type: string"}),"\n",(0,i.jsx)(n.li,{children:"Required: Yes"}),"\n",(0,i.jsxs)(n.li,{children:["Value: Richie ships with the following Javascript backends (custom backends can be written to\nfit another specific LMS):","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"openedx-dogwood"}),": backend for OpenEdX versions equal to ",(0,i.jsx)(n.code,{children:"dogwood"})," or ",(0,i.jsx)(n.code,{children:"eucalyptus"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"openedx-hawthorn"}),": backend for OpenEdX versions equal to ",(0,i.jsx)(n.code,{children:"hawthorn"})," or higher"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"openedx-fonzie"}),": backend for OpenEdX via ",(0,i.jsx)(n.a,{href:"https://github.com/openfun/fonzie",children:"Fonzie"}),"\n(extra user info and JWT tokens)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"dummy"}),": fake backend for development purposes"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"js_course_regex",children:"JS_COURSE_REGEX"}),"\n",(0,i.jsx)(n.p,{children:"A Javascript regex that should match the course syllabus urls of the targeted LMS and return an\nunnamed group on the id of the course extracted from these urls."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type: string"}),"\n",(0,i.jsx)(n.li,{children:"Required: Yes"}),"\n",(0,i.jsxs)(n.li,{children:["Value: for example ",(0,i.jsx)(n.code,{children:"^.*/courses/(.*)/course/?$"})]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"default_course_run_sync_mode",children:"DEFAULT_COURSE_RUN_SYNC_MODE"}),"\n",(0,i.jsxs)(n.p,{children:["When a course run is created, this setting is used to set the value of the ",(0,i.jsx)(n.code,{children:"sync_mode"})," field.\nThis value defines how the course runs synchronization script will impact this course run after\ncreation."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type: enum(string)"}),"\n",(0,i.jsx)(n.li,{children:"Required: No"}),"\n",(0,i.jsxs)(n.li,{children:["Value: possible values are ",(0,i.jsx)(n.code,{children:"manual"}),", ",(0,i.jsx)(n.code,{children:"sync_to_draft"})," and ",(0,i.jsx)(n.code,{children:"sync_to_public"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"manual"}),": this course run is ignored by the course runs synchronization script"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"sync_to_draft"}),": only the draft version of this course run is synchronized. A manual\npublication is necessary for the update to be visible on the public site."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"sync_to_public"}),": the public version of this course run is updated by the synchronization\nscript. As a results, updates are directly visible on the public site without further\npublication by a staff user in Richie."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"course_run_sync_no_update_fields",children:"COURSE_RUN_SYNC_NO_UPDATE_FIELDS"}),"\n",(0,i.jsx)(n.p,{children:"A list of fields that must only be set the first time a course run is synchronized. During this\nfirst synchronization, a new course run is created in Richie and all fields sent to the API\nendpoint via the payload are set on the object. For subsequent synchronization calls, the fields\nlisted in this setting are ignored and not synchronized. This can be used to allow modifying some\nfields manually in Richie regardless of what OpenEdX sends after an initial value is set."}),"\n",(0,i.jsxs)(n.p,{children:["Note that this setting is only effective for course runs with the ",(0,i.jsx)(n.code,{children:"sync_mode"})," field set to a\nvalue other then ",(0,i.jsx)(n.code,{children:"manual"}),"."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type: enum(string)"}),"\n",(0,i.jsx)(n.li,{children:"Required: No"}),"\n",(0,i.jsx)(n.li,{children:'Value: for example ["languages"]'}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"technical-support",children:"Technical support"}),"\n",(0,i.jsxs)(n.p,{children:["If you encounter an issue with this documentation or the backends included in Richie, please\n",(0,i.jsx)(n.a,{href:"https://github.com/openfun/richie/issues",children:"open an issue on our repository"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["If you need a custom backend, you can ",(0,i.jsx)(n.a,{href:"https://github.com/openfun/richie/pulls",children:"submit a PR"})," or\n",(0,i.jsx)(n.a,{href:"https://github.com/openfun/richie/issues",children:"open an issue"})," and we will consider adding it."]})]})}function h(e={}){const{wrapper:n}={...(0,r.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},11151:(e,n,s)=>{s.d(n,{Z:()=>t,a:()=>c});var i=s(67294);const r={},o=i.createContext(r);function c(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0293ad88.fff4af89.js b/assets/js/0293ad88.fff4af89.js deleted file mode 100644 index 07badfcef1..0000000000 --- a/assets/js/0293ad88.fff4af89.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[9831],{29454:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>t,default:()=>h,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var i=s(85893),r=s(11151);const o={id:"lms-backends",title:"Configuring LMS Backends",sidebar_label:"LMS Backends"},t=void 0,c={id:"lms-backends",title:"Configuring LMS Backends",description:"Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless",source:"@site/../docs/lms-backends.md",sourceDirName:".",slug:"/lms-backends",permalink:"/docs/next/lms-backends",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"jbpenrath",lastUpdatedAt:1652968488,formattedLastUpdatedAt:"May 19, 2022",frontMatter:{id:"lms-backends",title:"Configuring LMS Backends",sidebar_label:"LMS Backends"}},d={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Configuring the LMS handler",id:"configuring-the-lms-handler",level:2},{value:"BASE_URL",id:"base_url",level:3},{value:"BACKEND",id:"backend",level:3},{value:"COURSE_REGEX",id:"course_regex",level:3},{value:"JS_BACKEND",id:"js_backend",level:3},{value:"JS_COURSE_REGEX",id:"js_course_regex",level:3},{value:"DEFAULT_COURSE_RUN_SYNC_MODE",id:"default_course_run_sync_mode",level:3},{value:"COURSE_RUN_SYNC_NO_UPDATE_FIELDS",id:"course_run_sync_no_update_fields",level:3},{value:"Technical support",id:"technical-support",level:2}];function a(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.p,{children:"Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless\nexperience between browsing the course catalog on Richie, enrolling to a course and following the\ncourse itself on the LMS."}),"\n",(0,i.jsx)(n.p,{children:"It is possible to do the same with Moodle or any other LMS exposing an enrollment API, at the\ncost of writing a custom LMS handler backend."}),"\n",(0,i.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsxs)(n.p,{children:["This connection requires that Richie and OpenEdX be hosted on sibling domains i.e. domains that\nare both subdomains of the same root domain, e.g. ",(0,i.jsx)(n.code,{children:"richie.example.com"})," and ",(0,i.jsx)(n.code,{children:"lms.example.com"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"OpenEdX will need to generate a CORS CSRF Cookie and this cookie is flagged as secure, which\nimplies that we are not able to use it without SSL connections."}),"\n",(0,i.jsx)(n.p,{children:"As a consequence, you need to configure your OpenEdX instance as follows:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'FEATURES = {\n ...\n "ENABLE_CORS_HEADERS": True,\n "ENABLE_CROSS_DOMAIN_CSRF_COOKIE": True,\n}\n\nCORS_ALLOW_CREDENTIALS = True\nCORS_ALLOW_INSECURE = False\nCORS_ORIGIN_WHITELIST: ["richie.example.com"] # The domain on which Richie is hosted\n\nCROSS_DOMAIN_CSRF_COOKIE_DOMAIN = ".example.com" # The parent domain shared by Richie and OpenEdX\nCROSS_DOMAIN_CSRF_COOKIE_NAME: "edx_csrf_token"\nSESSION_COOKIE_NAME: "edx_session"\n'})}),"\n",(0,i.jsx)(n.h2,{id:"configuring-the-lms-handler",children:"Configuring the LMS handler"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"LMSHandler"})," utility acts as a proxy that routes queries to the correct LMS backend API,\nbased on a regex match on the URL of the course. It is configured via the ",(0,i.jsx)(n.code,{children:"RICHIE_LMS_BACKENDS"}),"\nsetting. As an example, here is how it would be configured to connect to an Ironwood OpenEdX\ninstance hosted on ",(0,i.jsx)(n.code,{children:"https://lms.example.com"}),":"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'RICHIE_LMS_BACKENDS=[\n {\n "BASE_URL": "https://lms.example.com",\n # Django\n "BACKEND": "richie.apps.courses.lms.edx.EdXLMSBackend",\n "COURSE_REGEX": r"^https://lms\\.example\\.com/courses/(?P.*)/course/?$",\n # ReactJS\n "JS_BACKEND": "openedx-hawthorn",\n "JS_COURSE_REGEX": r"^https://lms\\.example\\.com/courses/(.*)/course/?$",\n # Course runs synchronization\n "COURSE_RUN_SYNC_NO_UPDATE_FIELDS": [],\n "DEFAULT_COURSE_RUN_SYNC_MODE": "sync_to_public",\n },\n]\n'})}),"\n",(0,i.jsx)(n.p,{children:"The following should help you understand how to configure this setting:"}),"\n",(0,i.jsx)(n.h3,{id:"base_url",children:"BASE_URL"}),"\n",(0,i.jsx)(n.p,{children:"The base url on which the OpenEdX instance is hosted. This is used to construct the complete url\nof the API endpoint on which the enrollment request is made by Richie's frontend application."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type: string"}),"\n",(0,i.jsx)(n.li,{children:"Required: Yes"}),"\n",(0,i.jsxs)(n.li,{children:["Value: for example ",(0,i.jsx)(n.a,{href:"https://lms.example.com",children:"https://lms.example.com"})]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"backend",children:"BACKEND"}),"\n",(0,i.jsx)(n.p,{children:"The path to a Python class serving as LMS backend for the targeted LMS."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type: string"}),"\n",(0,i.jsx)(n.li,{children:"Required: Yes"}),"\n",(0,i.jsxs)(n.li,{children:["Value: Richie ships with the following Python backends (custom backends can be written to fit\nanother specific LMS):","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"richie.apps.courses.lms.edx.EdXLMSBackend"}),": backend for OpenEdX"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"richie.apps.courses.lms.base.BaseLMSBackend"}),": fake backend for development purposes"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"course_regex",children:"COURSE_REGEX"}),"\n",(0,i.jsxs)(n.p,{children:["A Python regex that should match the course syllabus urls of the targeted LMS and return a\n",(0,i.jsx)(n.code,{children:"course_id"})," named group on the id of the course extracted from these urls."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type: string"}),"\n",(0,i.jsx)(n.li,{children:"Required: Yes"}),"\n",(0,i.jsxs)(n.li,{children:["Value: for example ",(0,i.jsx)(n.code,{children:"^.*/courses/(?P.*)/course/?$"})]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"js_backend",children:"JS_BACKEND"}),"\n",(0,i.jsx)(n.p,{children:"The name of the ReactJS backend to use for the targeted LMS."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type: string"}),"\n",(0,i.jsx)(n.li,{children:"Required: Yes"}),"\n",(0,i.jsxs)(n.li,{children:["Value: Richie ships with the following Javascript backends (custom backends can be written to\nfit another specific LMS):","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"openedx-dogwood"}),": backend for OpenEdX versions equal to ",(0,i.jsx)(n.code,{children:"dogwood"})," or ",(0,i.jsx)(n.code,{children:"eucalyptus"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"openedx-hawthorn"}),": backend for OpenEdX versions equal to ",(0,i.jsx)(n.code,{children:"hawthorn"})," or higher"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"openedx-fonzie"}),": backend for OpenEdX via ",(0,i.jsx)(n.a,{href:"https://github.com/openfun/fonzie",children:"Fonzie"}),"\n(extra user info and JWT tokens)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"dummy"}),": fake backend for development purposes"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"js_course_regex",children:"JS_COURSE_REGEX"}),"\n",(0,i.jsx)(n.p,{children:"A Javascript regex that should match the course syllabus urls of the targeted LMS and return an\nunnamed group on the id of the course extracted from these urls."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type: string"}),"\n",(0,i.jsx)(n.li,{children:"Required: Yes"}),"\n",(0,i.jsxs)(n.li,{children:["Value: for example ",(0,i.jsx)(n.code,{children:"^.*/courses/(.*)/course/?$"})]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"default_course_run_sync_mode",children:"DEFAULT_COURSE_RUN_SYNC_MODE"}),"\n",(0,i.jsxs)(n.p,{children:["When a course run is created, this setting is used to set the value of the ",(0,i.jsx)(n.code,{children:"sync_mode"})," field.\nThis value defines how the course runs synchronization script will impact this course run after\ncreation."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type: enum(string)"}),"\n",(0,i.jsx)(n.li,{children:"Required: No"}),"\n",(0,i.jsxs)(n.li,{children:["Value: possible values are ",(0,i.jsx)(n.code,{children:"manual"}),", ",(0,i.jsx)(n.code,{children:"sync_to_draft"})," and ",(0,i.jsx)(n.code,{children:"sync_to_public"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"manual"}),": this course run is ignored by the course runs synchronization script"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"sync_to_draft"}),": only the draft version of this course run is synchronized. A manual\npublication is necessary for the update to be visible on the public site."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"sync_to_public"}),": the public version of this course run is updated by the synchronization\nscript. As a results, updates are directly visible on the public site without further\npublication by a staff user in Richie."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"course_run_sync_no_update_fields",children:"COURSE_RUN_SYNC_NO_UPDATE_FIELDS"}),"\n",(0,i.jsx)(n.p,{children:"A list of fields that must only be set the first time a course run is synchronized. During this\nfirst synchronization, a new course run is created in Richie and all fields sent to the API\nendpoint via the payload are set on the object. For subsequent synchronization calls, the fields\nlisted in this setting are ignored and not synchronized. This can be used to allow modifying some\nfields manually in Richie regardless of what OpenEdX sends after an initial value is set."}),"\n",(0,i.jsxs)(n.p,{children:["Note that this setting is only effective for course runs with the ",(0,i.jsx)(n.code,{children:"sync_mode"})," field set to a\nvalue other then ",(0,i.jsx)(n.code,{children:"manual"}),"."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type: enum(string)"}),"\n",(0,i.jsx)(n.li,{children:"Required: No"}),"\n",(0,i.jsx)(n.li,{children:'Value: for example ["languages"]'}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"technical-support",children:"Technical support"}),"\n",(0,i.jsxs)(n.p,{children:["If you encounter an issue with this documentation or the backends included in Richie, please\n",(0,i.jsx)(n.a,{href:"https://github.com/openfun/richie/issues",children:"open an issue on our repository"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["If you need a custom backend, you can ",(0,i.jsx)(n.a,{href:"https://github.com/openfun/richie/pulls",children:"submit a PR"})," or\n",(0,i.jsx)(n.a,{href:"https://github.com/openfun/richie/issues",children:"open an issue"})," and we will consider adding it."]})]})}function h(e={}){const{wrapper:n}={...(0,r.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},11151:(e,n,s)=>{s.d(n,{Z:()=>c,a:()=>t});var i=s(67294);const r={},o=i.createContext(r);function t(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:t(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/02a6e85d.d4fafaee.js b/assets/js/02a6e85d.d4fafaee.js new file mode 100644 index 0000000000..0db4e8b45a --- /dev/null +++ b/assets/js/02a6e85d.d4fafaee.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[4882],{24432:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var s=i(85893),t=i(11151);const o={id:"displaying-connection-status",title:"Displaying OpenEdX connection status in Richie",sidebar_label:"Displaying connection status"},r=void 0,l={id:"displaying-connection-status",title:"Displaying OpenEdX connection status in Richie",description:"This guide explains how to configure Richie and OpenEdX to share the OpenEdX connection status",source:"@site/versioned_docs/version-2.20.1/displaying-connection-status.md",sourceDirName:".",slug:"/displaying-connection-status",permalink:"/docs/2.20.1/displaying-connection-status",draft:!1,unlisted:!1,tags:[],version:"2.20.1",lastUpdatedBy:"jbpenrath",lastUpdatedAt:1677062183e3,frontMatter:{id:"displaying-connection-status",title:"Displaying OpenEdX connection status in Richie",sidebar_label:"Displaying connection status"}},a={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Allow redirects",id:"allow-redirects",level:2},{value:"Configure authentication delegation",id:"configure-authentication-delegation",level:2},{value:"BASE_URL",id:"base_url",level:3},{value:"BACKEND",id:"backend",level:3},{value:"PROFILE_URLS",id:"profile_urls",level:3}];function d(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,t.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:"This guide explains how to configure Richie and OpenEdX to share the OpenEdX connection status\nand display profile information for the logged-in user in Richie."}),"\n",(0,s.jsx)(n.p,{children:"In Richie, the only users that are actually authenticated on the DjangoCMS instance producing the\nsite, are editors and staff users. Your instructors and learners will not have user accounts on\nRichie, but authentication is delegated to a remote service that can be OpenEdX, KeyCloack, or\nyour own centralized identity management service."}),"\n",(0,s.jsx)(n.p,{children:"In the following, we will explain how to use OpenEdX as your authentication delegation service."}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsx)(n.p,{children:"Richie will need to make CORS requests to the OpenEdX instance. As a consequence, you need to\nactivate CORS requests on your OpenEdX instance:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'FEATURES = {\n ...\n "ENABLE_CORS_HEADERS": True,\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"Then, make sure the following settings are set as follows on your OpenEdX instance:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'CORS_ALLOW_CREDENTIALS = True\nCORS_ALLOW_INSECURE = False\nCORS_ORIGIN_ALLOW_ALL = False\nCORS_ORIGIN_WHITELIST: ["richie.example.com"] # The domain on which Richie is hosted\n'})}),"\n",(0,s.jsx)(n.h2,{id:"allow-redirects",children:"Allow redirects"}),"\n",(0,s.jsxs)(n.p,{children:["When Richie sends the user to the OpenEdX instance for authentication, and wants OpenEdX to\nredirect the user back to Richie after a successful login or signup, it prefixes the path with\n",(0,s.jsx)(n.code,{children:"/richie"}),". Adding the following rule to your Nginx server (or equivalent) and replacing the\nrichie host by yours will allow this redirect to follow through to your Richie instance:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"rewrite ^/richie/(.*)$ https://richie.example.com/$1 permanent;\n"})}),"\n",(0,s.jsx)(n.h2,{id:"configure-authentication-delegation",children:"Configure authentication delegation"}),"\n",(0,s.jsxs)(n.p,{children:["Now, on your Richie instance, you need to configure the service to which Richie will delegate\nauthentication using the ",(0,s.jsx)(n.code,{children:"RICHIE_AUTHENTICATION_DELEGATION"})," setting:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'RICHIE_AUTHENTICATION_DELEGATION = {\n "BASE_URL": "https://lms.example.com",\n "BACKEND": "openedx-hawthorn",\n "PROFILE_URLS": {\n "dashboard": {\n "label": _("Dashboard"),\n "href": "{base_url:s}/dashboard",\n },\n },\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"The following should help you understand how to configure this setting:"}),"\n",(0,s.jsx)(n.h3,{id:"base_url",children:"BASE_URL"}),"\n",(0,s.jsx)(n.p,{children:"The base url on which the OpenEdX instance is hosted. This is used to construct the complete url\nof the login/signup pages to which the frontend application will send the user for authentication."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Type: string"}),"\n",(0,s.jsx)(n.li,{children:"Required: Yes"}),"\n",(0,s.jsxs)(n.li,{children:["Value: for example ",(0,s.jsx)(n.a,{href:"https://lms.example.com",children:"https://lms.example.com"})]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"backend",children:"BACKEND"}),"\n",(0,s.jsx)(n.p,{children:"The name of the ReactJS backend to use for the targeted LMS."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Type: string"}),"\n",(0,s.jsx)(n.li,{children:"Required: Yes"}),"\n",(0,s.jsxs)(n.li,{children:["Value: Richie ships with the following Javascript backends:","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"openedx-dogwood"}),": backend for OpenEdX versions equal to ",(0,s.jsx)(n.code,{children:"dogwood"})," or ",(0,s.jsx)(n.code,{children:"eucalyptus"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"openedx-hawthorn"}),": backend for OpenEdX versions equal to ",(0,s.jsx)(n.code,{children:"hawthorn"})," or higher"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"openedx-fonzie"}),": backend for OpenEdX via ",(0,s.jsx)(n.a,{href:"https://github.com/openfun/fonzie",children:"Fonzie"}),"\n(extra user info and JWT tokens)"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"base"}),": fake backend for development purposes"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"profile_urls",children:"PROFILE_URLS"}),"\n",(0,s.jsx)(n.p,{children:"Mapping definition of custom links presented to the logged-in user as a dropdown menu when he/she\nclicks on his/her username in Richie's page header."}),"\n",(0,s.jsx)(n.p,{children:"Links order will be respected to build the dropdown menu."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Type: dictionary"}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Required: No"}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Value: For example, to emulate the links proposed in OpenEdX, you can configure this setting\nas follows:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:' {\n "dashboard": {\n "label": _("Dashboard"),\n "href": "{base_url:s}/dashboard",\n },\n "profile": {\n "label": _("Profile"),\n "href": "{base_url:s}/u/(username)",\n },\n "account": {\n "label": _("Account"),\n "href": "{base_url:s}/account/settings",\n }\n }\n'})}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"base_url"})," variable is used as a Python format parameter and will be replaced by the value\nset for the above authentication delegation ",(0,s.jsx)(n.code,{children:"BASE_URL"})," setting."]}),"\n",(0,s.jsxs)(n.p,{children:["If you need to bind user data into a url, wrap the property between brackets. For example, the\nlink configured above for the profile page ",(0,s.jsx)(n.code,{children:"{base_url:s}/u/(username)"})," would point to\n",(0,s.jsx)(n.code,{children:"https://lms.example.com/u/johndoe"})," for a user carrying the username ",(0,s.jsx)(n.code,{children:"johndoe"}),"."]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,t.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},11151:(e,n,i)=>{i.d(n,{Z:()=>l,a:()=>r});var s=i(67294);const t={},o=s.createContext(t);function r(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/02a6e85d.d7aeadaa.js b/assets/js/02a6e85d.d7aeadaa.js deleted file mode 100644 index 5f9f133798..0000000000 --- a/assets/js/02a6e85d.d7aeadaa.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[4882],{24432:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>a,toc:()=>c});var s=i(85893),t=i(11151);const o={id:"displaying-connection-status",title:"Displaying OpenEdX connection status in Richie",sidebar_label:"Displaying connection status"},r=void 0,a={id:"displaying-connection-status",title:"Displaying OpenEdX connection status in Richie",description:"This guide explains how to configure Richie and OpenEdX to share the OpenEdX connection status",source:"@site/versioned_docs/version-2.20.1/displaying-connection-status.md",sourceDirName:".",slug:"/displaying-connection-status",permalink:"/docs/2.20.1/displaying-connection-status",draft:!1,unlisted:!1,tags:[],version:"2.20.1",lastUpdatedBy:"jbpenrath",lastUpdatedAt:1677062183,formattedLastUpdatedAt:"Feb 22, 2023",frontMatter:{id:"displaying-connection-status",title:"Displaying OpenEdX connection status in Richie",sidebar_label:"Displaying connection status"}},l={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Allow redirects",id:"allow-redirects",level:2},{value:"Configure authentication delegation",id:"configure-authentication-delegation",level:2},{value:"BASE_URL",id:"base_url",level:3},{value:"BACKEND",id:"backend",level:3},{value:"PROFILE_URLS",id:"profile_urls",level:3}];function d(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,t.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:"This guide explains how to configure Richie and OpenEdX to share the OpenEdX connection status\nand display profile information for the logged-in user in Richie."}),"\n",(0,s.jsx)(n.p,{children:"In Richie, the only users that are actually authenticated on the DjangoCMS instance producing the\nsite, are editors and staff users. Your instructors and learners will not have user accounts on\nRichie, but authentication is delegated to a remote service that can be OpenEdX, KeyCloack, or\nyour own centralized identity management service."}),"\n",(0,s.jsx)(n.p,{children:"In the following, we will explain how to use OpenEdX as your authentication delegation service."}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsx)(n.p,{children:"Richie will need to make CORS requests to the OpenEdX instance. As a consequence, you need to\nactivate CORS requests on your OpenEdX instance:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'FEATURES = {\n ...\n "ENABLE_CORS_HEADERS": True,\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"Then, make sure the following settings are set as follows on your OpenEdX instance:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'CORS_ALLOW_CREDENTIALS = True\nCORS_ALLOW_INSECURE = False\nCORS_ORIGIN_ALLOW_ALL = False\nCORS_ORIGIN_WHITELIST: ["richie.example.com"] # The domain on which Richie is hosted\n'})}),"\n",(0,s.jsx)(n.h2,{id:"allow-redirects",children:"Allow redirects"}),"\n",(0,s.jsxs)(n.p,{children:["When Richie sends the user to the OpenEdX instance for authentication, and wants OpenEdX to\nredirect the user back to Richie after a successful login or signup, it prefixes the path with\n",(0,s.jsx)(n.code,{children:"/richie"}),". Adding the following rule to your Nginx server (or equivalent) and replacing the\nrichie host by yours will allow this redirect to follow through to your Richie instance:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"rewrite ^/richie/(.*)$ https://richie.example.com/$1 permanent;\n"})}),"\n",(0,s.jsx)(n.h2,{id:"configure-authentication-delegation",children:"Configure authentication delegation"}),"\n",(0,s.jsxs)(n.p,{children:["Now, on your Richie instance, you need to configure the service to which Richie will delegate\nauthentication using the ",(0,s.jsx)(n.code,{children:"RICHIE_AUTHENTICATION_DELEGATION"})," setting:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'RICHIE_AUTHENTICATION_DELEGATION = {\n "BASE_URL": "https://lms.example.com",\n "BACKEND": "openedx-hawthorn",\n "PROFILE_URLS": {\n "dashboard": {\n "label": _("Dashboard"),\n "href": "{base_url:s}/dashboard",\n },\n },\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"The following should help you understand how to configure this setting:"}),"\n",(0,s.jsx)(n.h3,{id:"base_url",children:"BASE_URL"}),"\n",(0,s.jsx)(n.p,{children:"The base url on which the OpenEdX instance is hosted. This is used to construct the complete url\nof the login/signup pages to which the frontend application will send the user for authentication."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Type: string"}),"\n",(0,s.jsx)(n.li,{children:"Required: Yes"}),"\n",(0,s.jsxs)(n.li,{children:["Value: for example ",(0,s.jsx)(n.a,{href:"https://lms.example.com",children:"https://lms.example.com"})]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"backend",children:"BACKEND"}),"\n",(0,s.jsx)(n.p,{children:"The name of the ReactJS backend to use for the targeted LMS."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Type: string"}),"\n",(0,s.jsx)(n.li,{children:"Required: Yes"}),"\n",(0,s.jsxs)(n.li,{children:["Value: Richie ships with the following Javascript backends:","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"openedx-dogwood"}),": backend for OpenEdX versions equal to ",(0,s.jsx)(n.code,{children:"dogwood"})," or ",(0,s.jsx)(n.code,{children:"eucalyptus"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"openedx-hawthorn"}),": backend for OpenEdX versions equal to ",(0,s.jsx)(n.code,{children:"hawthorn"})," or higher"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"openedx-fonzie"}),": backend for OpenEdX via ",(0,s.jsx)(n.a,{href:"https://github.com/openfun/fonzie",children:"Fonzie"}),"\n(extra user info and JWT tokens)"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"base"}),": fake backend for development purposes"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"profile_urls",children:"PROFILE_URLS"}),"\n",(0,s.jsx)(n.p,{children:"Mapping definition of custom links presented to the logged-in user as a dropdown menu when he/she\nclicks on his/her username in Richie's page header."}),"\n",(0,s.jsx)(n.p,{children:"Links order will be respected to build the dropdown menu."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Type: dictionary"}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Required: No"}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Value: For example, to emulate the links proposed in OpenEdX, you can configure this setting\nas follows:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:' {\n "dashboard": {\n "label": _("Dashboard"),\n "href": "{base_url:s}/dashboard",\n },\n "profile": {\n "label": _("Profile"),\n "href": "{base_url:s}/u/(username)",\n },\n "account": {\n "label": _("Account"),\n "href": "{base_url:s}/account/settings",\n }\n }\n'})}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"base_url"})," variable is used as a Python format parameter and will be replaced by the value\nset for the above authentication delegation ",(0,s.jsx)(n.code,{children:"BASE_URL"})," setting."]}),"\n",(0,s.jsxs)(n.p,{children:["If you need to bind user data into a url, wrap the property between brackets. For example, the\nlink configured above for the profile page ",(0,s.jsx)(n.code,{children:"{base_url:s}/u/(username)"})," would point to\n",(0,s.jsx)(n.code,{children:"https://lms.example.com/u/johndoe"})," for a user carrying the username ",(0,s.jsx)(n.code,{children:"johndoe"}),"."]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,t.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},11151:(e,n,i)=>{i.d(n,{Z:()=>a,a:()=>r});var s=i(67294);const t={},o=s.createContext(t);function r(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/02aff391.0126c97b.js b/assets/js/02aff391.0126c97b.js new file mode 100644 index 0000000000..3fa64e6589 --- /dev/null +++ b/assets/js/02aff391.0126c97b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[27128],{92485:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>r,metadata:()=>d,toc:()=>a});var t=i(85893),o=i(11151);const r={id:"building-the-frontend",title:"Building Richie's frontend in your own project",sidebar_label:"Building the frontend"},s=void 0,d={id:"building-the-frontend",title:"Building Richie's frontend in your own project",description:"Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.",source:"@site/versioned_docs/version-2.21.0/building-the-frontend.md",sourceDirName:".",slug:"/building-the-frontend",permalink:"/docs/2.21.0/building-the-frontend",draft:!1,unlisted:!1,tags:[],version:"2.21.0",lastUpdatedBy:"jbpenrath",lastUpdatedAt:1679473023e3,frontMatter:{id:"building-the-frontend",title:"Building Richie's frontend in your own project",sidebar_label:"Building the frontend"},sidebar:"docs",previous:{title:"Django & React",permalink:"/docs/2.21.0/django-react-interop"},next:{title:"Frontend overrides",permalink:"/docs/2.21.0/frontend-overrides"}},c={},a=[{value:"Installing richie-education",id:"installing-richie-education",level:2},{value:"Building the Javascript bundle",id:"building-the-javascript-bundle",level:2},{value:"Building the CSS",id:"building-the-css",level:2}];function l(e){const n={code:"code",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.p,{children:"Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings."}),"\n",(0,t.jsx)(n.p,{children:"Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend."}),"\n",(0,t.jsxs)(n.h2,{id:"installing-richie-education",children:["Installing ",(0,t.jsx)(n.code,{children:"richie-education"})]}),"\n",(0,t.jsx)(n.p,{children:"If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"mkdir -p src/frontend\n"})}),"\n",(0,t.jsx)(n.p,{children:"Then, you need to bootstrap your own frontend project in this new directory."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cd src/frontend\nyarn init\n"})}),"\n",(0,t.jsxs)(n.p,{children:["With each version of Richie, we build and publish an ",(0,t.jsx)(n.code,{children:"NPM"})," package to enable Richie users to build their own Javascript and CSS. You're now ready to install it."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"yarn add richie-education\n"})}),"\n",(0,t.jsxs)(n.p,{children:["In your ",(0,t.jsx)(n.code,{children:"package.json"})," file, you should see it in the list of dependencies. Also, there's a ",(0,t.jsx)(n.code,{children:"node_modules"})," directory where the package and its dependencies are actually installed."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"dependencies": {\n "richie-education": "1.12.0"\n},\n'})}),"\n",(0,t.jsx)(n.h2,{id:"building-the-javascript-bundle",children:"Building the Javascript bundle"}),"\n",(0,t.jsx)(n.p,{children:"You are now ready to run your own frontend build. We'll just be using webpack directly."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"yarn webpack --config node_modules/richie-education/webpack.config.js --output-path ./build --richie-dependent-build\n"})}),"\n",(0,t.jsx)(n.p,{children:"Here is everything that is happening:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"yarn webpack"})," \u2014 run the webpack CLI;"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"--config node_modules/richie-education/webpack.config.js"})," \u2014 point webpack to ",(0,t.jsx)(n.code,{children:"richie-education"}),"'s webpack config file;"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"--output-path ./build"})," \u2014 make sure we get our output where we need it to be;"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"--richie-dependent-build"})," \u2014 enable some affordances with import paths. We pre-configured Richie's webpack to be able to run it from a dependent project."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"You can now run your build to change frontend settings or override frontend components with your own."}),"\n",(0,t.jsx)(n.h2,{id:"building-the-css",children:"Building the CSS"}),"\n",(0,t.jsx)(n.p,{children:"If you want to change styles in Richie, or add new styles for components & templates you develop yourself, you can run the SASS/CSS build yourself."}),"\n",(0,t.jsxs)(n.p,{children:["Start by creating your own ",(0,t.jsx)(n.code,{children:"main"})," file. The ",(0,t.jsx)(n.code,{children:"_"})," underscore at the beginning is there to prevent sass from auto-compiling the file."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"mkdir -p src/frontend/scss\ntouch src/frontend/scss/_mains.scss\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Start by importing Richie's main scss file. If you prefer, you can also directly import any files you want to include \u2014 in effect re-doing Richie's ",(0,t.jsx)(n.code,{children:"_main.scss"})," on your own."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sass",children:'@import "richie-education/scss/main";\n'})}),"\n",(0,t.jsx)(n.p,{children:"You are now ready to run the CSS build:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"cd src/frontend\nyarn build-sass\n"})}),"\n",(0,t.jsx)(n.p,{children:"This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts."})]})}function u(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},11151:(e,n,i)=>{i.d(n,{Z:()=>d,a:()=>s});var t=i(67294);const o={},r=t.createContext(o);function s(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/02aff391.34c4176e.js b/assets/js/02aff391.34c4176e.js deleted file mode 100644 index 0e918c3ac3..0000000000 --- a/assets/js/02aff391.34c4176e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[27128],{92485:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>r,metadata:()=>d,toc:()=>a});var t=i(85893),o=i(11151);const r={id:"building-the-frontend",title:"Building Richie's frontend in your own project",sidebar_label:"Building the frontend"},s=void 0,d={id:"building-the-frontend",title:"Building Richie's frontend in your own project",description:"Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.",source:"@site/versioned_docs/version-2.21.0/building-the-frontend.md",sourceDirName:".",slug:"/building-the-frontend",permalink:"/docs/2.21.0/building-the-frontend",draft:!1,unlisted:!1,tags:[],version:"2.21.0",lastUpdatedBy:"jbpenrath",lastUpdatedAt:1679473023,formattedLastUpdatedAt:"Mar 22, 2023",frontMatter:{id:"building-the-frontend",title:"Building Richie's frontend in your own project",sidebar_label:"Building the frontend"},sidebar:"docs",previous:{title:"Django & React",permalink:"/docs/2.21.0/django-react-interop"},next:{title:"Frontend overrides",permalink:"/docs/2.21.0/frontend-overrides"}},c={},a=[{value:"Installing richie-education",id:"installing-richie-education",level:2},{value:"Building the Javascript bundle",id:"building-the-javascript-bundle",level:2},{value:"Building the CSS",id:"building-the-css",level:2}];function l(e){const n={code:"code",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.p,{children:"Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings."}),"\n",(0,t.jsx)(n.p,{children:"Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend."}),"\n",(0,t.jsxs)(n.h2,{id:"installing-richie-education",children:["Installing ",(0,t.jsx)(n.code,{children:"richie-education"})]}),"\n",(0,t.jsx)(n.p,{children:"If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"mkdir -p src/frontend\n"})}),"\n",(0,t.jsx)(n.p,{children:"Then, you need to bootstrap your own frontend project in this new directory."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cd src/frontend\nyarn init\n"})}),"\n",(0,t.jsxs)(n.p,{children:["With each version of Richie, we build and publish an ",(0,t.jsx)(n.code,{children:"NPM"})," package to enable Richie users to build their own Javascript and CSS. You're now ready to install it."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"yarn add richie-education\n"})}),"\n",(0,t.jsxs)(n.p,{children:["In your ",(0,t.jsx)(n.code,{children:"package.json"})," file, you should see it in the list of dependencies. Also, there's a ",(0,t.jsx)(n.code,{children:"node_modules"})," directory where the package and its dependencies are actually installed."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"dependencies": {\n "richie-education": "1.12.0"\n},\n'})}),"\n",(0,t.jsx)(n.h2,{id:"building-the-javascript-bundle",children:"Building the Javascript bundle"}),"\n",(0,t.jsx)(n.p,{children:"You are now ready to run your own frontend build. We'll just be using webpack directly."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"yarn webpack --config node_modules/richie-education/webpack.config.js --output-path ./build --richie-dependent-build\n"})}),"\n",(0,t.jsx)(n.p,{children:"Here is everything that is happening:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"yarn webpack"})," \u2014 run the webpack CLI;"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"--config node_modules/richie-education/webpack.config.js"})," \u2014 point webpack to ",(0,t.jsx)(n.code,{children:"richie-education"}),"'s webpack config file;"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"--output-path ./build"})," \u2014 make sure we get our output where we need it to be;"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"--richie-dependent-build"})," \u2014 enable some affordances with import paths. We pre-configured Richie's webpack to be able to run it from a dependent project."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"You can now run your build to change frontend settings or override frontend components with your own."}),"\n",(0,t.jsx)(n.h2,{id:"building-the-css",children:"Building the CSS"}),"\n",(0,t.jsx)(n.p,{children:"If you want to change styles in Richie, or add new styles for components & templates you develop yourself, you can run the SASS/CSS build yourself."}),"\n",(0,t.jsxs)(n.p,{children:["Start by creating your own ",(0,t.jsx)(n.code,{children:"main"})," file. The ",(0,t.jsx)(n.code,{children:"_"})," underscore at the beginning is there to prevent sass from auto-compiling the file."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"mkdir -p src/frontend/scss\ntouch src/frontend/scss/_mains.scss\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Start by importing Richie's main scss file. If you prefer, you can also directly import any files you want to include \u2014 in effect re-doing Richie's ",(0,t.jsx)(n.code,{children:"_main.scss"})," on your own."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sass",children:'@import "richie-education/scss/main";\n'})}),"\n",(0,t.jsx)(n.p,{children:"You are now ready to run the CSS build:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"cd src/frontend\nyarn build-sass\n"})}),"\n",(0,t.jsx)(n.p,{children:"This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts."})]})}function u(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},11151:(e,n,i)=>{i.d(n,{Z:()=>d,a:()=>s});var t=i(67294);const o={},r=t.createContext(o);function s(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/02fbc50f.06a2e257.js b/assets/js/02fbc50f.06a2e257.js deleted file mode 100644 index d264f573a1..0000000000 --- a/assets/js/02fbc50f.06a2e257.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[60274],{19950:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>h,frontMatter:()=>t,metadata:()=>c,toc:()=>d});var s=i(85893),o=i(11151);const t={id:"joanie-connection",title:"Joanie Connection",sidebar_label:"Joanie Connection"},r=void 0,c={id:"joanie-connection",title:"Joanie Connection",description:"Joanie delivers an API able to manage course",source:"@site/versioned_docs/version-2.25.0-beta.1/joanie-connection.md",sourceDirName:".",slug:"/joanie-connection",permalink:"/docs/2.25.0-beta.1/joanie-connection",draft:!1,unlisted:!1,tags:[],version:"2.25.0-beta.1",lastUpdatedBy:"jbpenrath",lastUpdatedAt:1704462108,formattedLastUpdatedAt:"Jan 5, 2024",frontMatter:{id:"joanie-connection",title:"Joanie Connection",sidebar_label:"Joanie Connection"}},a={},d=[{value:"Configuring Joanie",id:"configuring-joanie",level:2},{value:"BASE_URL",id:"base_url",level:3},{value:"BACKEND",id:"backend",level:3},{value:"JS_BACKEND",id:"js_backend",level:3},{value:"COURSE_REGEX",id:"course_regex",level:3},{value:"JS_COURSE_REGEX",id:"js_course_regex",level:3},{value:"COURSE_RUN_SYNC_NO_UPDATE_FIELDS",id:"course_run_sync_no_update_fields",level:3},{value:"DEFAULT_COURSE_RUN_SYNC_MODE",id:"default_course_run_sync_mode",level:3},{value:"Access Token",id:"access-token",level:2},{value:"Lifetime configuration",id:"lifetime-configuration",level:3},{value:"Technical support",id:"technical-support",level:2}];function l(e){const n={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"https://github.com/openfun/joanie",children:"Joanie"})," delivers an API able to manage course\nenrollment/subscription, payment and certificates delivery. Richie can be configured to display\ncourse runs and micro-credentials managed through Joanie."]}),"\n",(0,s.jsxs)(n.p,{children:["In fact, Richie treats Joanie almost like a ",(0,s.jsx)(n.a,{href:"/docs/2.25.0-beta.1/lms-backends",children:"LMS backend"})," that's why settings\nare similars."]}),"\n",(0,s.jsx)(n.h2,{id:"configuring-joanie",children:"Configuring Joanie"}),"\n",(0,s.jsxs)(n.p,{children:["All settings related to Joanie have to be declared in the ",(0,s.jsx)(n.code,{children:"JOANIE_BACKEND"})," dictionnary\nwithin ",(0,s.jsx)(n.code,{children:"settings.py"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'JOANIE_BACKEND = {\n "BASE_URL": values.Value(environ_name="JOANIE_BASE_URL", environ_prefix=None),\n "BACKEND": values.Value("richie.apps.courses.lms.joanie.JoanieBackend", environ_name="JOANIE_BACKEND", environ_prefix=None),\n "JS_BACKEND": values.Value("joanie", environ_name="JOANIE_JS_BACKEND", environ_prefix=None),\n "COURSE_REGEX": values.Value(\n r"^.*/api/v1.0(?P(?:/(?:courses|course-runs|products)/[^/]+)+)/?$",\n environ_name="JOANIE_COURSE_REGEX",\n environ_prefix=None,\n ),\n "JS_COURSE_REGEX": values.Value(\n r"^.*/api/v1.0((?:/(?:courses|course-runs|products)/[^/]+)+)/?$",\n environ_name="JOANIE_JS_COURSE_REGEX",\n environ_prefix=None,\n ),\n # Course runs synchronization\n "COURSE_RUN_SYNC_NO_UPDATE_FIELDS": [],\n "DEFAULT_COURSE_RUN_SYNC_MODE": "sync_to_public",\n}\n...\n'})}),"\n",(0,s.jsxs)(n.p,{children:["As mentioned earlier, Joanie is treated as a LMS by Richie, so we have to bind Joanie settings with\nLMS backends settings. We achieve this by dynamically appending the ",(0,s.jsx)(n.code,{children:"JOANIE_BACKEND"})," setting value\ninto the ",(0,s.jsx)(n.code,{children:"RICHIE_LMS_BACKENDS"})," list, if Joanie is enabled. To understand this point, you can take a\nlook at the ",(0,s.jsx)(n.code,{children:"post_setup"})," method of the Base class configuration into ",(0,s.jsx)(n.code,{children:"settings.py"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Here they are all settings available into ",(0,s.jsx)(n.code,{children:"JOANIE_BACKEND"}),":"]}),"\n",(0,s.jsx)(n.h3,{id:"base_url",children:"BASE_URL"}),"\n",(0,s.jsxs)(n.p,{children:["The base url on which the Joanie instance is hosted. This is used to construct the complete url of\nthe API endpoint on which requests are made by Richie's frontend application. ",(0,s.jsx)(n.em,{children:"Richie checks if this\nsettings is set to know if Joanie should be enabled or not."})]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Type: string"}),"\n",(0,s.jsx)(n.li,{children:"Required: Yes"}),"\n",(0,s.jsxs)(n.li,{children:["Value: for example ",(0,s.jsx)(n.a,{href:"https://joanie.example.com",children:"https://joanie.example.com"})]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"backend",children:"BACKEND"}),"\n",(0,s.jsx)(n.p,{children:"The path to a Python class serving as Joanie backend. You should not need to change this setting\nuntil you want to customize the behavior of the python Joanie backend."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Type: string"}),"\n",(0,s.jsx)(n.li,{children:"Required: No"}),"\n",(0,s.jsxs)(n.li,{children:["Value: By default it is ",(0,s.jsx)(n.code,{children:"richie.apps.courses.lms.joanie.JoanieBackend"})]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"js_backend",children:"JS_BACKEND"}),"\n",(0,s.jsx)(n.p,{children:"The name of the ReactJS backend to use Joanie. You should not need to change this setting\nuntil you want to customize the behavior of the js Joanie backend."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Type: string"}),"\n",(0,s.jsx)(n.li,{children:"Required: No"}),"\n",(0,s.jsxs)(n.li,{children:["Value: By default it is ",(0,s.jsx)(n.code,{children:"joanie"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"course_regex",children:"COURSE_REGEX"}),"\n",(0,s.jsxs)(n.p,{children:["A python regex that should match the ressource api urls of Joanie and return a\n",(0,s.jsx)(n.code,{children:"resource_uri"})," named group. The ",(0,s.jsx)(n.code,{children:"resource_uri"})," group should contain the url part containing\nall resources type and id implied.\ne.g: ",(0,s.jsx)(n.code,{children:"https://joanie.test/courses/00003/products/000001/"})," -> ",(0,s.jsx)(n.code,{children:"/courses/00003/products/000001"})]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Type: string"}),"\n",(0,s.jsx)(n.li,{children:"Required: No"}),"\n",(0,s.jsxs)(n.li,{children:["Value: for example ",(0,s.jsx)(n.code,{children:'r"^.*/api/v1.0(?P(?:/(?:courses|course-runs|products)/[^/]+)+)/?$"'})]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"js_course_regex",children:"JS_COURSE_REGEX"}),"\n",(0,s.jsxs)(n.p,{children:["A Javascript regex that should match the ressource api urls of Joanie and return an unamed group\ncorresponding to the ",(0,s.jsx)(n.code,{children:"resource_uri"})," named group described in ",(0,s.jsx)(n.code,{children:"COURSE_REGEX"})," section. Extracting\nproperly this information is mandatory as this group is parsed under the hood\nby the frontend application to extract resource types and resource ids."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Type: string"}),"\n",(0,s.jsx)(n.li,{children:"Required: No"}),"\n",(0,s.jsxs)(n.li,{children:["Value: for example ",(0,s.jsx)(n.code,{children:'r"^.*/api/v1.0((?:/(?:courses|course-runs|products)/[^/]+)+)/?$"'})]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"course_run_sync_no_update_fields",children:"COURSE_RUN_SYNC_NO_UPDATE_FIELDS"}),"\n",(0,s.jsx)(n.p,{children:"A list of fields that must only be set the first time a course run is synchronized. During this\nfirst synchronization, a new course run is created in Richie and all fields sent to the API\nendpoint via the payload are set on the object. For subsequent synchronization calls, the fields\nlisted in this setting are ignored and not synchronized. This can be used to allow modifying some\nfields manually in Richie regardless of what OpenEdX sends after an initial value is set."}),"\n",(0,s.jsxs)(n.p,{children:["Read documentation of ",(0,s.jsxs)(n.a,{href:"/docs/2.25.0-beta.1/lms-backends#course_run_sync_no_update_fields",children:["the eponym ",(0,s.jsx)(n.code,{children:"LMS_BACKENDS"})," settings"]}),",\nto discover how it can be configured."]}),"\n",(0,s.jsx)(n.h3,{id:"default_course_run_sync_mode",children:"DEFAULT_COURSE_RUN_SYNC_MODE"}),"\n",(0,s.jsxs)(n.p,{children:["Joanie resources (course runs and products) are all synchronized with Richie as a CourseRun. This\nsetting is used to set the value of the ",(0,s.jsx)(n.code,{children:"sync_mode"})," field when a course run is created on Richie.\nRead documentation of ",(0,s.jsxs)(n.a,{href:"/docs/2.25.0-beta.1/lms-backends#default_course_run_sync_mode",children:["the eponym ",(0,s.jsx)(n.code,{children:"LMS_BACKENDS"})," settings"]}),",\nto discover how it can be configured."]}),"\n",(0,s.jsx)(n.h2,{id:"access-token",children:"Access Token"}),"\n",(0,s.jsx)(n.h3,{id:"lifetime-configuration",children:"Lifetime configuration"}),"\n",(0,s.jsxs)(n.p,{children:["Access Token is stored within the SessionStorage through ",(0,s.jsx)(n.a,{href:"https://tanstack.com/query/v4/docs/plugins/persistQueryClient",children:"react-query client persister"}),".\nBy default, richie frontend considered access token as stale after 5 minutes. You can change this\nvalue into ",(0,s.jsx)(n.a,{href:"https://github.com/openfun/richie/blob/643d7bbdb7f9a02a86360607a7b37c587e70be1a/src/frontend/js/settings.ts",children:(0,s.jsx)(n.code,{children:"settings.ts"})}),"\nby editing ",(0,s.jsx)(n.code,{children:"REACT_QUERY_SETTINGS.staleTimes.session"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["To always have a valid access token, you have to configure properly its stale time according to the\nlifetime of the access token defined by your authentication server. For example, if your\nauthentication server is using ",(0,s.jsx)(n.code,{children:"djangorestframework-simplejwt"})," to generate the access token,\nits lifetime is 5 minutes by default."]}),"\n",(0,s.jsx)(n.h2,{id:"technical-support",children:"Technical support"}),"\n",(0,s.jsxs)(n.p,{children:["If you encounter an issue with this documentation, please\n",(0,s.jsx)(n.a,{href:"https://github.com/openfun/richie/issues",children:"open an issue on our repository"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},11151:(e,n,i)=>{i.d(n,{Z:()=>c,a:()=>r});var s=i(67294);const o={},t=s.createContext(o);function r(e){const n=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),s.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/02fbc50f.9f114b36.js b/assets/js/02fbc50f.9f114b36.js new file mode 100644 index 0000000000..5aa9d377d7 --- /dev/null +++ b/assets/js/02fbc50f.9f114b36.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[60274],{19950:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>h,frontMatter:()=>t,metadata:()=>c,toc:()=>d});var s=i(85893),o=i(11151);const t={id:"joanie-connection",title:"Joanie Connection",sidebar_label:"Joanie Connection"},r=void 0,c={id:"joanie-connection",title:"Joanie Connection",description:"Joanie delivers an API able to manage course",source:"@site/versioned_docs/version-2.25.0-beta.1/joanie-connection.md",sourceDirName:".",slug:"/joanie-connection",permalink:"/docs/2.25.0-beta.1/joanie-connection",draft:!1,unlisted:!1,tags:[],version:"2.25.0-beta.1",lastUpdatedBy:"jbpenrath",lastUpdatedAt:1704462108e3,frontMatter:{id:"joanie-connection",title:"Joanie Connection",sidebar_label:"Joanie Connection"}},a={},d=[{value:"Configuring Joanie",id:"configuring-joanie",level:2},{value:"BASE_URL",id:"base_url",level:3},{value:"BACKEND",id:"backend",level:3},{value:"JS_BACKEND",id:"js_backend",level:3},{value:"COURSE_REGEX",id:"course_regex",level:3},{value:"JS_COURSE_REGEX",id:"js_course_regex",level:3},{value:"COURSE_RUN_SYNC_NO_UPDATE_FIELDS",id:"course_run_sync_no_update_fields",level:3},{value:"DEFAULT_COURSE_RUN_SYNC_MODE",id:"default_course_run_sync_mode",level:3},{value:"Access Token",id:"access-token",level:2},{value:"Lifetime configuration",id:"lifetime-configuration",level:3},{value:"Technical support",id:"technical-support",level:2}];function l(e){const n={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"https://github.com/openfun/joanie",children:"Joanie"})," delivers an API able to manage course\nenrollment/subscription, payment and certificates delivery. Richie can be configured to display\ncourse runs and micro-credentials managed through Joanie."]}),"\n",(0,s.jsxs)(n.p,{children:["In fact, Richie treats Joanie almost like a ",(0,s.jsx)(n.a,{href:"/docs/2.25.0-beta.1/lms-backends",children:"LMS backend"})," that's why settings\nare similars."]}),"\n",(0,s.jsx)(n.h2,{id:"configuring-joanie",children:"Configuring Joanie"}),"\n",(0,s.jsxs)(n.p,{children:["All settings related to Joanie have to be declared in the ",(0,s.jsx)(n.code,{children:"JOANIE_BACKEND"})," dictionnary\nwithin ",(0,s.jsx)(n.code,{children:"settings.py"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'JOANIE_BACKEND = {\n "BASE_URL": values.Value(environ_name="JOANIE_BASE_URL", environ_prefix=None),\n "BACKEND": values.Value("richie.apps.courses.lms.joanie.JoanieBackend", environ_name="JOANIE_BACKEND", environ_prefix=None),\n "JS_BACKEND": values.Value("joanie", environ_name="JOANIE_JS_BACKEND", environ_prefix=None),\n "COURSE_REGEX": values.Value(\n r"^.*/api/v1.0(?P(?:/(?:courses|course-runs|products)/[^/]+)+)/?$",\n environ_name="JOANIE_COURSE_REGEX",\n environ_prefix=None,\n ),\n "JS_COURSE_REGEX": values.Value(\n r"^.*/api/v1.0((?:/(?:courses|course-runs|products)/[^/]+)+)/?$",\n environ_name="JOANIE_JS_COURSE_REGEX",\n environ_prefix=None,\n ),\n # Course runs synchronization\n "COURSE_RUN_SYNC_NO_UPDATE_FIELDS": [],\n "DEFAULT_COURSE_RUN_SYNC_MODE": "sync_to_public",\n}\n...\n'})}),"\n",(0,s.jsxs)(n.p,{children:["As mentioned earlier, Joanie is treated as a LMS by Richie, so we have to bind Joanie settings with\nLMS backends settings. We achieve this by dynamically appending the ",(0,s.jsx)(n.code,{children:"JOANIE_BACKEND"})," setting value\ninto the ",(0,s.jsx)(n.code,{children:"RICHIE_LMS_BACKENDS"})," list, if Joanie is enabled. To understand this point, you can take a\nlook at the ",(0,s.jsx)(n.code,{children:"post_setup"})," method of the Base class configuration into ",(0,s.jsx)(n.code,{children:"settings.py"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Here they are all settings available into ",(0,s.jsx)(n.code,{children:"JOANIE_BACKEND"}),":"]}),"\n",(0,s.jsx)(n.h3,{id:"base_url",children:"BASE_URL"}),"\n",(0,s.jsxs)(n.p,{children:["The base url on which the Joanie instance is hosted. This is used to construct the complete url of\nthe API endpoint on which requests are made by Richie's frontend application. ",(0,s.jsx)(n.em,{children:"Richie checks if this\nsettings is set to know if Joanie should be enabled or not."})]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Type: string"}),"\n",(0,s.jsx)(n.li,{children:"Required: Yes"}),"\n",(0,s.jsxs)(n.li,{children:["Value: for example ",(0,s.jsx)(n.a,{href:"https://joanie.example.com",children:"https://joanie.example.com"})]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"backend",children:"BACKEND"}),"\n",(0,s.jsx)(n.p,{children:"The path to a Python class serving as Joanie backend. You should not need to change this setting\nuntil you want to customize the behavior of the python Joanie backend."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Type: string"}),"\n",(0,s.jsx)(n.li,{children:"Required: No"}),"\n",(0,s.jsxs)(n.li,{children:["Value: By default it is ",(0,s.jsx)(n.code,{children:"richie.apps.courses.lms.joanie.JoanieBackend"})]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"js_backend",children:"JS_BACKEND"}),"\n",(0,s.jsx)(n.p,{children:"The name of the ReactJS backend to use Joanie. You should not need to change this setting\nuntil you want to customize the behavior of the js Joanie backend."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Type: string"}),"\n",(0,s.jsx)(n.li,{children:"Required: No"}),"\n",(0,s.jsxs)(n.li,{children:["Value: By default it is ",(0,s.jsx)(n.code,{children:"joanie"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"course_regex",children:"COURSE_REGEX"}),"\n",(0,s.jsxs)(n.p,{children:["A python regex that should match the ressource api urls of Joanie and return a\n",(0,s.jsx)(n.code,{children:"resource_uri"})," named group. The ",(0,s.jsx)(n.code,{children:"resource_uri"})," group should contain the url part containing\nall resources type and id implied.\ne.g: ",(0,s.jsx)(n.code,{children:"https://joanie.test/courses/00003/products/000001/"})," -> ",(0,s.jsx)(n.code,{children:"/courses/00003/products/000001"})]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Type: string"}),"\n",(0,s.jsx)(n.li,{children:"Required: No"}),"\n",(0,s.jsxs)(n.li,{children:["Value: for example ",(0,s.jsx)(n.code,{children:'r"^.*/api/v1.0(?P(?:/(?:courses|course-runs|products)/[^/]+)+)/?$"'})]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"js_course_regex",children:"JS_COURSE_REGEX"}),"\n",(0,s.jsxs)(n.p,{children:["A Javascript regex that should match the ressource api urls of Joanie and return an unamed group\ncorresponding to the ",(0,s.jsx)(n.code,{children:"resource_uri"})," named group described in ",(0,s.jsx)(n.code,{children:"COURSE_REGEX"})," section. Extracting\nproperly this information is mandatory as this group is parsed under the hood\nby the frontend application to extract resource types and resource ids."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Type: string"}),"\n",(0,s.jsx)(n.li,{children:"Required: No"}),"\n",(0,s.jsxs)(n.li,{children:["Value: for example ",(0,s.jsx)(n.code,{children:'r"^.*/api/v1.0((?:/(?:courses|course-runs|products)/[^/]+)+)/?$"'})]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"course_run_sync_no_update_fields",children:"COURSE_RUN_SYNC_NO_UPDATE_FIELDS"}),"\n",(0,s.jsx)(n.p,{children:"A list of fields that must only be set the first time a course run is synchronized. During this\nfirst synchronization, a new course run is created in Richie and all fields sent to the API\nendpoint via the payload are set on the object. For subsequent synchronization calls, the fields\nlisted in this setting are ignored and not synchronized. This can be used to allow modifying some\nfields manually in Richie regardless of what OpenEdX sends after an initial value is set."}),"\n",(0,s.jsxs)(n.p,{children:["Read documentation of ",(0,s.jsxs)(n.a,{href:"/docs/2.25.0-beta.1/lms-backends#course_run_sync_no_update_fields",children:["the eponym ",(0,s.jsx)(n.code,{children:"LMS_BACKENDS"})," settings"]}),",\nto discover how it can be configured."]}),"\n",(0,s.jsx)(n.h3,{id:"default_course_run_sync_mode",children:"DEFAULT_COURSE_RUN_SYNC_MODE"}),"\n",(0,s.jsxs)(n.p,{children:["Joanie resources (course runs and products) are all synchronized with Richie as a CourseRun. This\nsetting is used to set the value of the ",(0,s.jsx)(n.code,{children:"sync_mode"})," field when a course run is created on Richie.\nRead documentation of ",(0,s.jsxs)(n.a,{href:"/docs/2.25.0-beta.1/lms-backends#default_course_run_sync_mode",children:["the eponym ",(0,s.jsx)(n.code,{children:"LMS_BACKENDS"})," settings"]}),",\nto discover how it can be configured."]}),"\n",(0,s.jsx)(n.h2,{id:"access-token",children:"Access Token"}),"\n",(0,s.jsx)(n.h3,{id:"lifetime-configuration",children:"Lifetime configuration"}),"\n",(0,s.jsxs)(n.p,{children:["Access Token is stored within the SessionStorage through ",(0,s.jsx)(n.a,{href:"https://tanstack.com/query/v4/docs/plugins/persistQueryClient",children:"react-query client persister"}),".\nBy default, richie frontend considered access token as stale after 5 minutes. You can change this\nvalue into ",(0,s.jsx)(n.a,{href:"https://github.com/openfun/richie/blob/643d7bbdb7f9a02a86360607a7b37c587e70be1a/src/frontend/js/settings.ts",children:(0,s.jsx)(n.code,{children:"settings.ts"})}),"\nby editing ",(0,s.jsx)(n.code,{children:"REACT_QUERY_SETTINGS.staleTimes.session"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["To always have a valid access token, you have to configure properly its stale time according to the\nlifetime of the access token defined by your authentication server. For example, if your\nauthentication server is using ",(0,s.jsx)(n.code,{children:"djangorestframework-simplejwt"})," to generate the access token,\nits lifetime is 5 minutes by default."]}),"\n",(0,s.jsx)(n.h2,{id:"technical-support",children:"Technical support"}),"\n",(0,s.jsxs)(n.p,{children:["If you encounter an issue with this documentation, please\n",(0,s.jsx)(n.a,{href:"https://github.com/openfun/richie/issues",children:"open an issue on our repository"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},11151:(e,n,i)=>{i.d(n,{Z:()=>c,a:()=>r});var s=i(67294);const o={},t=s.createContext(o);function r(e){const n=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),s.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0386b2c0.26f5414a.js b/assets/js/0386b2c0.26f5414a.js deleted file mode 100644 index 4abd1ae89e..0000000000 --- a/assets/js/0386b2c0.26f5414a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[84648],{86352:(n,e,t)=>{t.r(e),t.d(e,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>s,toc:()=>c});var i=t(85893),o=t(11151);const a={id:"internationalization",title:"Internationalization",sidebar_label:"I18n"},r=void 0,s={id:"internationalization",title:"Internationalization",description:"richie has built-in localization and internationalization:",source:"@site/versioned_docs/version-2.7.0/internationalization.md",sourceDirName:".",slug:"/internationalization",permalink:"/docs/2.7.0/internationalization",draft:!1,unlisted:!1,tags:[],version:"2.7.0",lastUpdatedBy:"Mehdi Benadda",lastUpdatedAt:1655108611,formattedLastUpdatedAt:"Jun 13, 2022",frontMatter:{id:"internationalization",title:"Internationalization",sidebar_label:"I18n"},sidebar:"docs",previous:{title:"Building the frontend",permalink:"/docs/2.7.0/building-the-frontend"},next:{title:"Frontend overrides",permalink:"/docs/2.7.0/frontend-overrides"}},d={},c=[{value:"Contributing as a translator or proof-reader",id:"contributing-as-a-translator-or-proof-reader",level:2},{value:"Sign-up on Crowdin",id:"sign-up-on-crowdin",level:3},{value:"Join the Richie project",id:"join-the-richie-project",level:3},{value:"Add a new language",id:"add-a-new-language",level:3}];function l(n){const e={a:"a",code:"code",h2:"h2",h3:"h3",img:"img",li:"li",p:"p",ul:"ul",...(0,o.a)(),...n.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(e.p,{children:[(0,i.jsx)(e.code,{children:"richie"})," has built-in localization and internationalization:"]}),"\n",(0,i.jsxs)(e.ul,{children:["\n",(0,i.jsx)(e.li,{children:"On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,"}),"\n",(0,i.jsx)(e.li,{children:"On the frontend, we use React Intl."}),"\n"]}),"\n",(0,i.jsx)(e.h2,{id:"contributing-as-a-translator-or-proof-reader",children:"Contributing as a translator or proof-reader"}),"\n",(0,i.jsxs)(e.p,{children:["We use the ",(0,i.jsx)(e.a,{href:"https://crowdin.com",children:"Crowdin"})," web platform to translate Richie to different languages.\nAll translations are hosted at ",(0,i.jsx)(e.a,{href:"https://i18n.richie.education",children:"https://i18n.richie.education"}),", which allows translators and\nproof-readers to contribute on translations in the languages they master."]}),"\n",(0,i.jsx)(e.h3,{id:"sign-up-on-crowdin",children:"Sign-up on Crowdin"}),"\n",(0,i.jsxs)(e.p,{children:["If you don't have an account on Crowdin already, go to ",(0,i.jsx)(e.a,{href:"https://accounts.crowdin.com/register",children:"https://accounts.crowdin.com/register"})," and\nfill out the form to create a free account."]}),"\n",(0,i.jsx)(e.h3,{id:"join-the-richie-project",children:"Join the Richie project"}),"\n",(0,i.jsxs)(e.p,{children:["Now that you have an account on Crowdin,\n",(0,i.jsx)(e.a,{href:"https://crowdin.com/project/richie",children:'look for the project called "Richie"'}),', select the language\non which you wish to contribute and click the "Join" button as demonstrated below:']}),"\n",(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{alt:"How to join Richie on Crowdin",src:t(10188).Z+"",width:"2462",height:"1506"})}),"\n",(0,i.jsx)(e.p,{children:"We will then review you application and you should soon start translating strings!"}),"\n",(0,i.jsxs)(e.p,{children:["For more information on how Crowdin works, you can refer to\n",(0,i.jsx)(e.a,{href:"https://support.crowdin.com",children:"their documentation"}),"."]}),"\n",(0,i.jsx)(e.h3,{id:"add-a-new-language",children:"Add a new language"}),"\n",(0,i.jsxs)(e.p,{children:['If Richie is not yet translated in the language you want, let us know by clicking the "contact"\nlink on ',(0,i.jsx)(e.a,{href:"https://i18n.richie.education",children:"Richie's Crowdin profile page"})," and we will consider adding\nit."]}),"\n",(0,i.jsx)(e.p,{children:"If you request a new language, the Richie community will expect you to keep this language\nup-to-date each time strings are modified or new strings are added, and this before each\nrelease."}),"\n",(0,i.jsx)(e.p,{children:"Before asking for a new language, make sure it does not already exist. If your language already\nexists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider\ncontributing on the existing language if your resources to contribute are limited."})]})}function h(n={}){const{wrapper:e}={...(0,o.a)(),...n.components};return e?(0,i.jsx)(e,{...n,children:(0,i.jsx)(l,{...n})}):l(n)}},10188:(n,e,t)=>{t.d(e,{Z:()=>i});const i=t.p+"assets/images/crowdin-join-richie-fd505b1a132bafb2bdafc715649a7c0f.gif"},11151:(n,e,t)=>{t.d(e,{Z:()=>s,a:()=>r});var i=t(67294);const o={},a=i.createContext(o);function r(n){const e=i.useContext(a);return i.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function s(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(o):n.components||o:r(n.components),i.createElement(a.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/0386b2c0.49fc2b6a.js b/assets/js/0386b2c0.49fc2b6a.js new file mode 100644 index 0000000000..2ab82372f3 --- /dev/null +++ b/assets/js/0386b2c0.49fc2b6a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[84648],{86352:(n,e,i)=>{i.r(e),i.d(e,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>s,toc:()=>d});var t=i(85893),o=i(11151);const a={id:"internationalization",title:"Internationalization",sidebar_label:"I18n"},r=void 0,s={id:"internationalization",title:"Internationalization",description:"richie has built-in localization and internationalization:",source:"@site/versioned_docs/version-2.7.0/internationalization.md",sourceDirName:".",slug:"/internationalization",permalink:"/docs/2.7.0/internationalization",draft:!1,unlisted:!1,tags:[],version:"2.7.0",lastUpdatedBy:"Mehdi Benadda",lastUpdatedAt:1655108611e3,frontMatter:{id:"internationalization",title:"Internationalization",sidebar_label:"I18n"},sidebar:"docs",previous:{title:"Building the frontend",permalink:"/docs/2.7.0/building-the-frontend"},next:{title:"Frontend overrides",permalink:"/docs/2.7.0/frontend-overrides"}},c={},d=[{value:"Contributing as a translator or proof-reader",id:"contributing-as-a-translator-or-proof-reader",level:2},{value:"Sign-up on Crowdin",id:"sign-up-on-crowdin",level:3},{value:"Join the Richie project",id:"join-the-richie-project",level:3},{value:"Add a new language",id:"add-a-new-language",level:3}];function l(n){const e={a:"a",code:"code",h2:"h2",h3:"h3",img:"img",li:"li",p:"p",ul:"ul",...(0,o.a)(),...n.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:"richie"})," has built-in localization and internationalization:"]}),"\n",(0,t.jsxs)(e.ul,{children:["\n",(0,t.jsx)(e.li,{children:"On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,"}),"\n",(0,t.jsx)(e.li,{children:"On the frontend, we use React Intl."}),"\n"]}),"\n",(0,t.jsx)(e.h2,{id:"contributing-as-a-translator-or-proof-reader",children:"Contributing as a translator or proof-reader"}),"\n",(0,t.jsxs)(e.p,{children:["We use the ",(0,t.jsx)(e.a,{href:"https://crowdin.com",children:"Crowdin"})," web platform to translate Richie to different languages.\nAll translations are hosted at ",(0,t.jsx)(e.a,{href:"https://i18n.richie.education",children:"https://i18n.richie.education"}),", which allows translators and\nproof-readers to contribute on translations in the languages they master."]}),"\n",(0,t.jsx)(e.h3,{id:"sign-up-on-crowdin",children:"Sign-up on Crowdin"}),"\n",(0,t.jsxs)(e.p,{children:["If you don't have an account on Crowdin already, go to ",(0,t.jsx)(e.a,{href:"https://accounts.crowdin.com/register",children:"https://accounts.crowdin.com/register"})," and\nfill out the form to create a free account."]}),"\n",(0,t.jsx)(e.h3,{id:"join-the-richie-project",children:"Join the Richie project"}),"\n",(0,t.jsxs)(e.p,{children:["Now that you have an account on Crowdin,\n",(0,t.jsx)(e.a,{href:"https://crowdin.com/project/richie",children:'look for the project called "Richie"'}),', select the language\non which you wish to contribute and click the "Join" button as demonstrated below:']}),"\n",(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{alt:"How to join Richie on Crowdin",src:i(10188).Z+"",width:"2462",height:"1506"})}),"\n",(0,t.jsx)(e.p,{children:"We will then review you application and you should soon start translating strings!"}),"\n",(0,t.jsxs)(e.p,{children:["For more information on how Crowdin works, you can refer to\n",(0,t.jsx)(e.a,{href:"https://support.crowdin.com",children:"their documentation"}),"."]}),"\n",(0,t.jsx)(e.h3,{id:"add-a-new-language",children:"Add a new language"}),"\n",(0,t.jsxs)(e.p,{children:['If Richie is not yet translated in the language you want, let us know by clicking the "contact"\nlink on ',(0,t.jsx)(e.a,{href:"https://i18n.richie.education",children:"Richie's Crowdin profile page"})," and we will consider adding\nit."]}),"\n",(0,t.jsx)(e.p,{children:"If you request a new language, the Richie community will expect you to keep this language\nup-to-date each time strings are modified or new strings are added, and this before each\nrelease."}),"\n",(0,t.jsx)(e.p,{children:"Before asking for a new language, make sure it does not already exist. If your language already\nexists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider\ncontributing on the existing language if your resources to contribute are limited."})]})}function h(n={}){const{wrapper:e}={...(0,o.a)(),...n.components};return e?(0,t.jsx)(e,{...n,children:(0,t.jsx)(l,{...n})}):l(n)}},10188:(n,e,i)=>{i.d(e,{Z:()=>t});const t=i.p+"assets/images/crowdin-join-richie-fd505b1a132bafb2bdafc715649a7c0f.gif"},11151:(n,e,i)=>{i.d(e,{Z:()=>s,a:()=>r});var t=i(67294);const o={},a=t.createContext(o);function r(n){const e=t.useContext(a);return t.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function s(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(o):n.components||o:r(n.components),t.createElement(a.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/03a6f5b2.92d59349.js b/assets/js/03a6f5b2.92d59349.js new file mode 100644 index 0000000000..a02f225f5a --- /dev/null +++ b/assets/js/03a6f5b2.92d59349.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[12024],{31782:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>h,frontMatter:()=>s,metadata:()=>r,toc:()=>a});var t=o(85893),i=o(11151);const s={id:"lms-connection",title:"Connecting Richie with an LMS",sidebar_label:"LMS connection"},c=void 0,r={id:"lms-connection",title:"Connecting Richie with an LMS",description:"richie can be connected to one or more Learning Management Systems (LMS) like OpenEdx, Moodle",source:"@site/versioned_docs/version-2.0.0/lms-connection.md",sourceDirName:".",slug:"/lms-connection",permalink:"/docs/2.0.0/lms-connection",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mehdi Benadda",lastUpdatedAt:1655108611e3,frontMatter:{id:"lms-connection",title:"Connecting Richie with an LMS",sidebar_label:"LMS connection"},sidebar:"docs",previous:{title:"Frontend overrides",permalink:"/docs/2.0.0/frontend-overrides"},next:{title:"Contributing guide",permalink:"/docs/2.0.0/contributing-guide"}},d={},a=[{value:"API bridge",id:"api-bridge",level:3},{value:"Connecting Richie and OpenEdx over TLS",id:"connecting-richie-and-openedx-over-tls",level:2},{value:"Purpose",id:"purpose",level:4},{value:"Run OpenEdx and Richie on the same domain",id:"run-openedx-and-richie-on-the-same-domain",level:4},{value:"Enable TLS",id:"enable-tls",level:4},{value:"1. Install mkcert and its Certificate Authority",id:"1-install-mkcert-and-its-certificate-authority",level:5},{value:"a. Install mkcert on your local machine",id:"a-install-mkcert-on-your-local-machine",level:6},{value:"b. Install Mkcert Certificate Authority",id:"b-install-mkcert-certificate-authority",level:6},{value:"2. On Richie",id:"2-on-richie",level:5},{value:"3. On OpenEdx",id:"3-on-openedx",level:5},{value:"4. Start Richie and OpenEdx over SSL",id:"4-start-richie-and-openedx-over-ssl",level:5}];function l(e){const n={a:"a",blockquote:"blockquote",code:"code",em:"em",h2:"h2",h3:"h3",h4:"h4",h5:"h5",h6:"h6",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"richie"})," can be connected to one or more Learning Management Systems (LMS) like OpenEdx, Moodle\nor Canvas for a seamless experience between browsing the course catalog on ",(0,t.jsx)(n.code,{children:"richie"})," and following\nthe course itself on the LMS."]}),"\n",(0,t.jsxs)(n.p,{children:["In order to connect ",(0,t.jsx)(n.code,{children:"richie"})," with a LMS, there is an API bridge\nto synchronize course information and enrollments."]}),"\n",(0,t.jsx)(n.h3,{id:"api-bridge",children:"API bridge"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"APIHandler"})," utility acts as a proxy that routes queries to the correct LMS backend API,\nbased on a regex match on the URL of the course."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'RICHIE_LMS_BACKENDS=[\n {\n "BASE_URL": "https://www.lms-example2.org",\n "BACKEND": "richie.apps.courses.lms.edx.EdXLMSBackend",\n "COURSE_REGEX": r"^.*/courses/(?P.*)/course/?$",\n "JS_BACKEND": "openedx-hawthorn",\n "JS_SELECTOR_REGEX": r".*lms-example2.org.*",\n "JS_COURSE_REGEX": r"^.*/course/(?[0-9]*)$",\n },\n]\n'})}),"\n",(0,t.jsx)(n.p,{children:"For information about how to generate an API access on your OpenEdx instance, refer to the\ndocumentation."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsxs)(n.em,{children:["Note: ",(0,t.jsx)(n.code,{children:"JS_BACKEND"})," accepts ",(0,t.jsx)(n.code,{children:"base"}),", ",(0,t.jsx)(n.code,{children:"openedx-dogwood"})," and ",(0,t.jsx)(n.code,{children:"openedx-hawthorn"})," values."]}),"\n",(0,t.jsx)(n.em,{children:"We have to implement several interfaces to be compatible to OpenEdx API:"}),"\n",(0,t.jsxs)(n.em,{children:[(0,t.jsx)(n.code,{children:"openedx-dogwood"})," has been tested with Dogwood and Eucalyptus versions."]}),"\n",(0,t.jsxs)(n.em,{children:[(0,t.jsx)(n.code,{children:"openedx-hawthorn"})," has been tested with Hawthorn and Ironwood versions."]}),"\n",(0,t.jsx)(n.em,{children:"If you encounter an issue with these API interfaces or need to have a new interface, propose a PR"}),"\n",(0,t.jsx)(n.em,{children:"or create an issue on our repository"})]}),"\n",(0,t.jsx)(n.h2,{id:"connecting-richie-and-openedx-over-tls",children:"Connecting Richie and OpenEdx over TLS"}),"\n",(0,t.jsx)(n.h4,{id:"purpose",children:"Purpose"}),"\n",(0,t.jsxs)(n.p,{children:["About the default configuration, if you check ",(0,t.jsx)(n.code,{children:"RICHIE_LMS_BACKENDS"})," settings in ",(0,t.jsx)(n.code,{children:"env.d/development"}),"\nyou will see that we use ",(0,t.jsx)(n.code,{children:"base.BaseLMSBackend"})," as ",(0,t.jsx)(n.code,{children:"RICHIE_LMS_BACKENDS"}),".\nIn fact, this base backend uses session storage to fake enrollment to course runs."]}),"\n",(0,t.jsx)(n.p,{children:"Maybe are you asking why? Because, to make Create/Update/Delete requests from an external domain,\nOpenEdx requires the use of a CORS CSRF Cookie. This cookie is flagged as secure, that means we are\nnot able to use it without a SSL connection."}),"\n",(0,t.jsx)(n.p,{children:"So if you need to use the OpenEdx API to Create, Update or Delete data from Richie, you have to\nenable SSL on Richie and OpenEdx on your development environment. So we need a little bit more\nconfiguration. Below, we explain how to serve OpenEdx and Richie over SSL."}),"\n",(0,t.jsx)(n.h4,{id:"run-openedx-and-richie-on-the-same-domain",children:"Run OpenEdx and Richie on the same domain"}),"\n",(0,t.jsxs)(n.p,{children:["Richie and OpenEdx must be on the same domain to work properly (Cookie security policy blocks\nsecure cookie sharing on localhost) To do that you have to edit your hosts file\n(",(0,t.jsx)(n.em,{children:".e.g"})," ",(0,t.jsx)(n.code,{children:"/etc/hosts"})," on a *NIX system) to alias a domain ",(0,t.jsx)(n.code,{children:"local.dev"})," with\ntwo subdomains ",(0,t.jsx)(n.code,{children:"richie"})," and ",(0,t.jsx)(n.code,{children:"edx"})," to localhost:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"# /etc/hosts\n127.0.0.1 richie.local.dev\n127.0.0.1 edx.local.dev\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Once this has been done, the OpenEdx app should respond on ",(0,t.jsx)(n.a,{href:"http://edx.local.dev:8073",children:"http://edx.local.dev:8073"}),"\nand Richie should respond on ",(0,t.jsx)(n.a,{href:"http://richie.local.dev:8070",children:"http://richie.local.dev:8070"})," and should be able\nto make CORS XHR requests."]}),"\n",(0,t.jsx)(n.h4,{id:"enable-tls",children:"Enable TLS"}),"\n",(0,t.jsxs)(n.p,{children:["If you want to develop with OpenEdx as ",(0,t.jsx)(n.code,{children:"RICHIE_LMS_BACKENDS"})," of Richie, you need to enable TLS for your\ndevelopment servers. Both Richie and OpenEdx use Nginx as reverse proxy that ease the SSL setup."]}),"\n",(0,t.jsx)(n.h5,{id:"1-install-mkcert-and-its-certificate-authority",children:"1. Install mkcert and its Certificate Authority"}),"\n",(0,t.jsxs)(n.p,{children:["First you will need to install mkcert and its Certificate Authority.\n",(0,t.jsx)(n.a,{href:"https://mkcert.org/",children:"mkcert"})," is a little util to ease local certificate generation."]}),"\n",(0,t.jsxs)(n.h6,{id:"a-install-mkcert-on-your-local-machine",children:["a. Install ",(0,t.jsx)(n.code,{children:"mkcert"})," on your local machine"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://github.com/FiloSottile/mkcert",children:"Read the doc"})}),"\n",(0,t.jsxs)(n.li,{children:["Linux users who do not want to use linuxbrew : ",(0,t.jsx)(n.a,{href:"https://www.prado.lt/how-to-create-locally-trusted-ssl-certificates-in-local-development-environment-on-linux-with-mkcert",children:"read this article"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.h6,{id:"b-install-mkcert-certificate-authority",children:"b. Install Mkcert Certificate Authority"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"mkcert -install"})}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["If you do not want to use mkcert, you can generate ",(0,t.jsx)(n.a,{href:"https://www.freecodecamp.org/news/how-to-get-https-working-on-your-local-development-environment-in-5-minutes-7af615770eec/",children:"CA and certificate with openssl"}),".\nYou will have to put your certificate and its key in ",(0,t.jsx)(n.code,{children:"docker/files/etc/nginx/ssl"})," directory\nand named them ",(0,t.jsx)(n.code,{children:"richie.local.dev.pem"})," and ",(0,t.jsx)(n.code,{children:"richie.local.dev.key"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.h5,{id:"2-on-richie",children:"2. On Richie"}),"\n",(0,t.jsxs)(n.p,{children:["To setup SSL conf with mkcert, just run:\n",(0,t.jsx)(n.code,{children:"bin/setup-ssl"})]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["If you do not want to use mkcert, read instructions above to generate Richie certificate then\nrun ",(0,t.jsx)(n.code,{children:"bin/setup-ssl --no-cert"})," instead."]}),"\n"]}),"\n",(0,t.jsx)(n.h5,{id:"3-on-openedx",children:"3. On OpenEdx"}),"\n",(0,t.jsxs)(n.p,{children:["In the same way, about OpenEdx, you also have to update the Nginx configuration to enable SSL.\nRead how to ",(0,t.jsx)(n.a,{href:"https://github.com/openfun/openedx-docker#ssl",children:"enable SSL on OpenEdx"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Once this has been done, the OpenEdx app should respond on ",(0,t.jsx)(n.a,{href:"https://edx.local.dev:8073",children:"https://edx.local.dev:8073"}),"\nand Richie should respond on ",(0,t.jsx)(n.a,{href:"https://richie.local.dev:8070",children:"https://richie.local.dev:8070"})," and should be able\nto share cookies with OpenEdx to allow CORS CSRF Protected XHR requests."]}),"\n",(0,t.jsx)(n.h5,{id:"4-start-richie-and-openedx-over-ssl",children:"4. Start Richie and OpenEdx over SSL"}),"\n",(0,t.jsxs)(n.p,{children:["Now, OpenEdx app should respond on ",(0,t.jsx)(n.a,{href:"https://edx.local.dev:8073",children:"https://edx.local.dev:8073"}),", and Richie\non ",(0,t.jsx)(n.a,{href:"https://richie.local.dev:8070",children:"https://richie.local.dev:8070"})," without browser warning about the certificate validity."]}),"\n",(0,t.jsxs)(n.p,{children:["You need to follow these steps once. If you want to use SSL later, just use ",(0,t.jsx)(n.code,{children:"make run-ssl"})," to run\nOpenEdx and Richie apps.\nOf course, you can still run apps without ssl by using ",(0,t.jsx)(n.code,{children:"make run"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},11151:(e,n,o)=>{o.d(n,{Z:()=>r,a:()=>c});var t=o(67294);const i={},s=t.createContext(i);function c(e){const n=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),t.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/03a6f5b2.e2306470.js b/assets/js/03a6f5b2.e2306470.js deleted file mode 100644 index 4438800cc1..0000000000 --- a/assets/js/03a6f5b2.e2306470.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[12024],{31782:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>h,frontMatter:()=>s,metadata:()=>r,toc:()=>a});var t=o(85893),i=o(11151);const s={id:"lms-connection",title:"Connecting Richie with an LMS",sidebar_label:"LMS connection"},c=void 0,r={id:"lms-connection",title:"Connecting Richie with an LMS",description:"richie can be connected to one or more Learning Management Systems (LMS) like OpenEdx, Moodle",source:"@site/versioned_docs/version-2.0.0/lms-connection.md",sourceDirName:".",slug:"/lms-connection",permalink:"/docs/2.0.0/lms-connection",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mehdi Benadda",lastUpdatedAt:1655108611,formattedLastUpdatedAt:"Jun 13, 2022",frontMatter:{id:"lms-connection",title:"Connecting Richie with an LMS",sidebar_label:"LMS connection"},sidebar:"docs",previous:{title:"Frontend overrides",permalink:"/docs/2.0.0/frontend-overrides"},next:{title:"Contributing guide",permalink:"/docs/2.0.0/contributing-guide"}},d={},a=[{value:"API bridge",id:"api-bridge",level:3},{value:"Connecting Richie and OpenEdx over TLS",id:"connecting-richie-and-openedx-over-tls",level:2},{value:"Purpose",id:"purpose",level:4},{value:"Run OpenEdx and Richie on the same domain",id:"run-openedx-and-richie-on-the-same-domain",level:4},{value:"Enable TLS",id:"enable-tls",level:4},{value:"1. Install mkcert and its Certificate Authority",id:"1-install-mkcert-and-its-certificate-authority",level:5},{value:"a. Install mkcert on your local machine",id:"a-install-mkcert-on-your-local-machine",level:6},{value:"b. Install Mkcert Certificate Authority",id:"b-install-mkcert-certificate-authority",level:6},{value:"2. On Richie",id:"2-on-richie",level:5},{value:"3. On OpenEdx",id:"3-on-openedx",level:5},{value:"4. Start Richie and OpenEdx over SSL",id:"4-start-richie-and-openedx-over-ssl",level:5}];function l(e){const n={a:"a",blockquote:"blockquote",code:"code",em:"em",h2:"h2",h3:"h3",h4:"h4",h5:"h5",h6:"h6",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"richie"})," can be connected to one or more Learning Management Systems (LMS) like OpenEdx, Moodle\nor Canvas for a seamless experience between browsing the course catalog on ",(0,t.jsx)(n.code,{children:"richie"})," and following\nthe course itself on the LMS."]}),"\n",(0,t.jsxs)(n.p,{children:["In order to connect ",(0,t.jsx)(n.code,{children:"richie"})," with a LMS, there is an API bridge\nto synchronize course information and enrollments."]}),"\n",(0,t.jsx)(n.h3,{id:"api-bridge",children:"API bridge"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"APIHandler"})," utility acts as a proxy that routes queries to the correct LMS backend API,\nbased on a regex match on the URL of the course."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'RICHIE_LMS_BACKENDS=[\n {\n "BASE_URL": "https://www.lms-example2.org",\n "BACKEND": "richie.apps.courses.lms.edx.EdXLMSBackend",\n "COURSE_REGEX": r"^.*/courses/(?P.*)/course/?$",\n "JS_BACKEND": "openedx-hawthorn",\n "JS_SELECTOR_REGEX": r".*lms-example2.org.*",\n "JS_COURSE_REGEX": r"^.*/course/(?[0-9]*)$",\n },\n]\n'})}),"\n",(0,t.jsx)(n.p,{children:"For information about how to generate an API access on your OpenEdx instance, refer to the\ndocumentation."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsxs)(n.em,{children:["Note: ",(0,t.jsx)(n.code,{children:"JS_BACKEND"})," accepts ",(0,t.jsx)(n.code,{children:"base"}),", ",(0,t.jsx)(n.code,{children:"openedx-dogwood"})," and ",(0,t.jsx)(n.code,{children:"openedx-hawthorn"})," values."]}),"\n",(0,t.jsx)(n.em,{children:"We have to implement several interfaces to be compatible to OpenEdx API:"}),"\n",(0,t.jsxs)(n.em,{children:[(0,t.jsx)(n.code,{children:"openedx-dogwood"})," has been tested with Dogwood and Eucalyptus versions."]}),"\n",(0,t.jsxs)(n.em,{children:[(0,t.jsx)(n.code,{children:"openedx-hawthorn"})," has been tested with Hawthorn and Ironwood versions."]}),"\n",(0,t.jsx)(n.em,{children:"If you encounter an issue with these API interfaces or need to have a new interface, propose a PR"}),"\n",(0,t.jsx)(n.em,{children:"or create an issue on our repository"})]}),"\n",(0,t.jsx)(n.h2,{id:"connecting-richie-and-openedx-over-tls",children:"Connecting Richie and OpenEdx over TLS"}),"\n",(0,t.jsx)(n.h4,{id:"purpose",children:"Purpose"}),"\n",(0,t.jsxs)(n.p,{children:["About the default configuration, if you check ",(0,t.jsx)(n.code,{children:"RICHIE_LMS_BACKENDS"})," settings in ",(0,t.jsx)(n.code,{children:"env.d/development"}),"\nyou will see that we use ",(0,t.jsx)(n.code,{children:"base.BaseLMSBackend"})," as ",(0,t.jsx)(n.code,{children:"RICHIE_LMS_BACKENDS"}),".\nIn fact, this base backend uses session storage to fake enrollment to course runs."]}),"\n",(0,t.jsx)(n.p,{children:"Maybe are you asking why? Because, to make Create/Update/Delete requests from an external domain,\nOpenEdx requires the use of a CORS CSRF Cookie. This cookie is flagged as secure, that means we are\nnot able to use it without a SSL connection."}),"\n",(0,t.jsx)(n.p,{children:"So if you need to use the OpenEdx API to Create, Update or Delete data from Richie, you have to\nenable SSL on Richie and OpenEdx on your development environment. So we need a little bit more\nconfiguration. Below, we explain how to serve OpenEdx and Richie over SSL."}),"\n",(0,t.jsx)(n.h4,{id:"run-openedx-and-richie-on-the-same-domain",children:"Run OpenEdx and Richie on the same domain"}),"\n",(0,t.jsxs)(n.p,{children:["Richie and OpenEdx must be on the same domain to work properly (Cookie security policy blocks\nsecure cookie sharing on localhost) To do that you have to edit your hosts file\n(",(0,t.jsx)(n.em,{children:".e.g"})," ",(0,t.jsx)(n.code,{children:"/etc/hosts"})," on a *NIX system) to alias a domain ",(0,t.jsx)(n.code,{children:"local.dev"})," with\ntwo subdomains ",(0,t.jsx)(n.code,{children:"richie"})," and ",(0,t.jsx)(n.code,{children:"edx"})," to localhost:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"# /etc/hosts\n127.0.0.1 richie.local.dev\n127.0.0.1 edx.local.dev\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Once this has been done, the OpenEdx app should respond on ",(0,t.jsx)(n.a,{href:"http://edx.local.dev:8073",children:"http://edx.local.dev:8073"}),"\nand Richie should respond on ",(0,t.jsx)(n.a,{href:"http://richie.local.dev:8070",children:"http://richie.local.dev:8070"})," and should be able\nto make CORS XHR requests."]}),"\n",(0,t.jsx)(n.h4,{id:"enable-tls",children:"Enable TLS"}),"\n",(0,t.jsxs)(n.p,{children:["If you want to develop with OpenEdx as ",(0,t.jsx)(n.code,{children:"RICHIE_LMS_BACKENDS"})," of Richie, you need to enable TLS for your\ndevelopment servers. Both Richie and OpenEdx use Nginx as reverse proxy that ease the SSL setup."]}),"\n",(0,t.jsx)(n.h5,{id:"1-install-mkcert-and-its-certificate-authority",children:"1. Install mkcert and its Certificate Authority"}),"\n",(0,t.jsxs)(n.p,{children:["First you will need to install mkcert and its Certificate Authority.\n",(0,t.jsx)(n.a,{href:"https://mkcert.org/",children:"mkcert"})," is a little util to ease local certificate generation."]}),"\n",(0,t.jsxs)(n.h6,{id:"a-install-mkcert-on-your-local-machine",children:["a. Install ",(0,t.jsx)(n.code,{children:"mkcert"})," on your local machine"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://github.com/FiloSottile/mkcert",children:"Read the doc"})}),"\n",(0,t.jsxs)(n.li,{children:["Linux users who do not want to use linuxbrew : ",(0,t.jsx)(n.a,{href:"https://www.prado.lt/how-to-create-locally-trusted-ssl-certificates-in-local-development-environment-on-linux-with-mkcert",children:"read this article"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.h6,{id:"b-install-mkcert-certificate-authority",children:"b. Install Mkcert Certificate Authority"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"mkcert -install"})}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["If you do not want to use mkcert, you can generate ",(0,t.jsx)(n.a,{href:"https://www.freecodecamp.org/news/how-to-get-https-working-on-your-local-development-environment-in-5-minutes-7af615770eec/",children:"CA and certificate with openssl"}),".\nYou will have to put your certificate and its key in ",(0,t.jsx)(n.code,{children:"docker/files/etc/nginx/ssl"})," directory\nand named them ",(0,t.jsx)(n.code,{children:"richie.local.dev.pem"})," and ",(0,t.jsx)(n.code,{children:"richie.local.dev.key"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.h5,{id:"2-on-richie",children:"2. On Richie"}),"\n",(0,t.jsxs)(n.p,{children:["To setup SSL conf with mkcert, just run:\n",(0,t.jsx)(n.code,{children:"bin/setup-ssl"})]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["If you do not want to use mkcert, read instructions above to generate Richie certificate then\nrun ",(0,t.jsx)(n.code,{children:"bin/setup-ssl --no-cert"})," instead."]}),"\n"]}),"\n",(0,t.jsx)(n.h5,{id:"3-on-openedx",children:"3. On OpenEdx"}),"\n",(0,t.jsxs)(n.p,{children:["In the same way, about OpenEdx, you also have to update the Nginx configuration to enable SSL.\nRead how to ",(0,t.jsx)(n.a,{href:"https://github.com/openfun/openedx-docker#ssl",children:"enable SSL on OpenEdx"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Once this has been done, the OpenEdx app should respond on ",(0,t.jsx)(n.a,{href:"https://edx.local.dev:8073",children:"https://edx.local.dev:8073"}),"\nand Richie should respond on ",(0,t.jsx)(n.a,{href:"https://richie.local.dev:8070",children:"https://richie.local.dev:8070"})," and should be able\nto share cookies with OpenEdx to allow CORS CSRF Protected XHR requests."]}),"\n",(0,t.jsx)(n.h5,{id:"4-start-richie-and-openedx-over-ssl",children:"4. Start Richie and OpenEdx over SSL"}),"\n",(0,t.jsxs)(n.p,{children:["Now, OpenEdx app should respond on ",(0,t.jsx)(n.a,{href:"https://edx.local.dev:8073",children:"https://edx.local.dev:8073"}),", and Richie\non ",(0,t.jsx)(n.a,{href:"https://richie.local.dev:8070",children:"https://richie.local.dev:8070"})," without browser warning about the certificate validity."]}),"\n",(0,t.jsxs)(n.p,{children:["You need to follow these steps once. If you want to use SSL later, just use ",(0,t.jsx)(n.code,{children:"make run-ssl"})," to run\nOpenEdx and Richie apps.\nOf course, you can still run apps without ssl by using ",(0,t.jsx)(n.code,{children:"make run"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},11151:(e,n,o)=>{o.d(n,{Z:()=>r,a:()=>c});var t=o(67294);const i={},s=t.createContext(i);function c(e){const n=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),t.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/03e22855.0b6f1028.js b/assets/js/03e22855.0b6f1028.js new file mode 100644 index 0000000000..81931f1c1d --- /dev/null +++ b/assets/js/03e22855.0b6f1028.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[71267],{92288:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>c,toc:()=>a});var t=o(85893),i=o(11151);const s={id:"discover",title:"Getting started with Richie",sidebar_label:"Quick start"},r=void 0,c={id:"discover",title:"Getting started with Richie",description:"If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.",source:"@site/versioned_docs/version-2.3.1/quick-start.md",sourceDirName:".",slug:"/discover",permalink:"/docs/2.3.1/discover",draft:!1,unlisted:!1,tags:[],version:"2.3.1",lastUpdatedBy:"Mehdi Benadda",lastUpdatedAt:1655108611e3,frontMatter:{id:"discover",title:"Getting started with Richie",sidebar_label:"Quick start"},sidebar:"docs",next:{title:"Docker development",permalink:"/docs/2.3.1/docker-development"}},d={},a=[{value:"Architecture",id:"architecture",level:2},{value:"Getting started",id:"getting-started",level:2},{value:"Docker",id:"docker",level:3},{value:"Project bootstrap",id:"project-bootstrap",level:3},{value:"Adding content",id:"adding-content",level:3},{value:"Basic - Connecting Richie to OpenEdx",id:"basic---connecting-richie-to-openedx",level:3},{value:"Advanced - Connecting Richie to OpenEdx",id:"advanced---connecting-richie-to-openedx",level:3}];function l(e){const n={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)(n.p,{children:["If you're just looking for a quick preview of ",(0,t.jsx)(n.code,{children:"Richie"}),", you can take a look and have a tour of ",(0,t.jsx)(n.code,{children:"Richie"})," on our dedicated ",(0,t.jsx)(n.a,{href:"https://demo.richie.education",children:"demo site"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Login/password are ",(0,t.jsx)(n.code,{children:"admin"}),"/",(0,t.jsx)(n.code,{children:"admin"}),". The database is regularly flushed."]}),"\n",(0,t.jsx)(n.h2,{id:"architecture",children:"Architecture"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"Richie"})," is a ",(0,t.jsx)(n.strong,{children:"container-native application"})," but can also be installed\n",(0,t.jsx)(n.a,{href:"/docs/2.3.1/native-installation",children:"on your machine"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["For development, the project is defined using a ",(0,t.jsx)(n.a,{href:"../docker-compose.yml",children:"docker-compose file"})," and\nconsists of 4 services:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"db"}),": the ",(0,t.jsx)(n.code,{children:"Postgresql"})," database,"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"elasticsearch"}),": the search engine,"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"app"}),": the actual ",(0,t.jsx)(n.code,{children:"DjangoCMS"})," project with all our application code,"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"node"}),": used for front-end related tasks, ",(0,t.jsx)(n.em,{children:"i.e."})," transpiling ",(0,t.jsx)(n.code,{children:"TypeScript"})," sources, bundling\nthem into a JS package, and building the CSS files from Sass sources."]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:['At "France Universit\xe9 Num\xe9rique", we deploy our applications on ',(0,t.jsx)(n.code,{children:"OpenShift"}),"/",(0,t.jsx)(n.code,{children:"Kubernetes"})," using\n",(0,t.jsx)(n.a,{href:"https://github.com/openfun/arnold",children:(0,t.jsx)(n.code,{children:"Arnold"})}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"getting-started",children:"Getting started"}),"\n",(0,t.jsx)(n.h3,{id:"docker",children:"Docker"}),"\n",(0,t.jsxs)(n.p,{children:["First, make sure you have a recent version of Docker and\n",(0,t.jsx)(n.a,{href:"https://docs.docker.com/compose/install",children:"Docker Compose"})," installed on your laptop:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ docker -v\n Docker version 1.13.1, build 092cba3\n\n$ docker-compose --version\n docker-compose version 1.17.1, build 6d101fb\n"})}),"\n",(0,t.jsxs)(n.p,{children:["\u26a0\ufe0f You may need to run the following commands with ",(0,t.jsx)(n.code,{children:"sudo"})," but this can be avoided by assigning your\nuser to the ",(0,t.jsx)(n.code,{children:"docker"})," group."]}),"\n",(0,t.jsx)(n.h3,{id:"project-bootstrap",children:"Project bootstrap"}),"\n",(0,t.jsxs)(n.p,{children:["The easiest way to start working on the project is to use our ",(0,t.jsx)(n.code,{children:"Makefile"}),":"]}),"\n",(0,t.jsx)(n.p,{children:"$ make bootstrap"}),"\n",(0,t.jsxs)(n.p,{children:["This command builds the ",(0,t.jsx)(n.code,{children:"app"})," container, installs front-end and back-end dependencies, builds the\nfront-end application and styles, and performs database migrations. It's a good idea to use this\ncommand each time you are pulling code from the project repository to avoid dependency-related or\nmigration-related issues."]}),"\n",(0,t.jsxs)(n.p,{children:["Now that your ",(0,t.jsx)(n.code,{children:"Docker"})," services are ready to be used, start the full CMS by running:"]}),"\n",(0,t.jsx)(n.p,{children:"$ make run"}),"\n",(0,t.jsx)(n.h3,{id:"adding-content",children:"Adding content"}),"\n",(0,t.jsx)(n.p,{children:"Once the CMS is up and running, you can create a superuser account:"}),"\n",(0,t.jsx)(n.p,{children:"$ make superuser"}),"\n",(0,t.jsx)(n.p,{children:"You can create a basic demo site by running:"}),"\n",(0,t.jsx)(n.p,{children:"$ make demo-site"}),"\n",(0,t.jsx)(n.p,{children:"Note that if you don't create the demo site and start from a blank CMS, you will get some errors\nrequesting you to create some required root pages. So it is easier as a first approach to test the\nCMS with the demo site."}),"\n",(0,t.jsxs)(n.p,{children:["You should be able to view the site at ",(0,t.jsx)(n.a,{href:"http://localhost:8070",children:"localhost:8070"})]}),"\n",(0,t.jsx)(n.h3,{id:"basic---connecting-richie-to-openedx",children:"Basic - Connecting Richie to OpenEdx"}),"\n",(0,t.jsxs)(n.p,{children:["This project is pre-configured to connect with an OpenEdx instance started with\n[OpenEdx Docker](",(0,t.jsx)(n.a,{href:"https://github.com/openfun/openedx-docker",children:"https://github.com/openfun/openedx-docker"}),"], which provides a ready to use\ndocker-compose stack of OpenEdx in several flavors. Head over to\n",(0,t.jsx)(n.a,{href:"https://github.com/openfun/openedx-docker#readme",children:"OpenEdx Docker README"})," for instructions on how\nto bootstrap an instance."]}),"\n",(0,t.jsxs)(n.p,{children:["Just start apps with ",(0,t.jsx)(n.code,{children:"make run"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Richie should respond on ",(0,t.jsx)(n.code,{children:"http://localhost:8070"})," and OpenEdx on ",(0,t.jsx)(n.code,{children:"http://localhost:8073"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"advanced---connecting-richie-to-openedx",children:"Advanced - Connecting Richie to OpenEdx"}),"\n",(0,t.jsxs)(n.p,{children:["If you want users to enroll on courses in OpenEdx directly from Richie via API calls, you should\nread ",(0,t.jsx)(n.a,{href:"/docs/2.3.1/lms-connection#connecting-richie-and-openedx-over-tls",children:"the advanced guide"})," to connect\nRichie to OpenEdx over TLS."]})]})}function h(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},11151:(e,n,o)=>{o.d(n,{Z:()=>c,a:()=>r});var t=o(67294);const i={},s=t.createContext(i);function r(e){const n=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),t.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/03e22855.5db721db.js b/assets/js/03e22855.5db721db.js deleted file mode 100644 index 9119e41719..0000000000 --- a/assets/js/03e22855.5db721db.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[71267],{92288:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>c,toc:()=>a});var t=o(85893),i=o(11151);const s={id:"discover",title:"Getting started with Richie",sidebar_label:"Quick start"},r=void 0,c={id:"discover",title:"Getting started with Richie",description:"If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.",source:"@site/versioned_docs/version-2.3.1/quick-start.md",sourceDirName:".",slug:"/discover",permalink:"/docs/2.3.1/discover",draft:!1,unlisted:!1,tags:[],version:"2.3.1",lastUpdatedBy:"Mehdi Benadda",lastUpdatedAt:1655108611,formattedLastUpdatedAt:"Jun 13, 2022",frontMatter:{id:"discover",title:"Getting started with Richie",sidebar_label:"Quick start"},sidebar:"docs",next:{title:"Docker development",permalink:"/docs/2.3.1/docker-development"}},d={},a=[{value:"Architecture",id:"architecture",level:2},{value:"Getting started",id:"getting-started",level:2},{value:"Docker",id:"docker",level:3},{value:"Project bootstrap",id:"project-bootstrap",level:3},{value:"Adding content",id:"adding-content",level:3},{value:"Basic - Connecting Richie to OpenEdx",id:"basic---connecting-richie-to-openedx",level:3},{value:"Advanced - Connecting Richie to OpenEdx",id:"advanced---connecting-richie-to-openedx",level:3}];function l(e){const n={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)(n.p,{children:["If you're just looking for a quick preview of ",(0,t.jsx)(n.code,{children:"Richie"}),", you can take a look and have a tour of ",(0,t.jsx)(n.code,{children:"Richie"})," on our dedicated ",(0,t.jsx)(n.a,{href:"https://demo.richie.education",children:"demo site"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Login/password are ",(0,t.jsx)(n.code,{children:"admin"}),"/",(0,t.jsx)(n.code,{children:"admin"}),". The database is regularly flushed."]}),"\n",(0,t.jsx)(n.h2,{id:"architecture",children:"Architecture"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"Richie"})," is a ",(0,t.jsx)(n.strong,{children:"container-native application"})," but can also be installed\n",(0,t.jsx)(n.a,{href:"/docs/2.3.1/native-installation",children:"on your machine"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["For development, the project is defined using a ",(0,t.jsx)(n.a,{href:"../docker-compose.yml",children:"docker-compose file"})," and\nconsists of 4 services:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"db"}),": the ",(0,t.jsx)(n.code,{children:"Postgresql"})," database,"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"elasticsearch"}),": the search engine,"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"app"}),": the actual ",(0,t.jsx)(n.code,{children:"DjangoCMS"})," project with all our application code,"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"node"}),": used for front-end related tasks, ",(0,t.jsx)(n.em,{children:"i.e."})," transpiling ",(0,t.jsx)(n.code,{children:"TypeScript"})," sources, bundling\nthem into a JS package, and building the CSS files from Sass sources."]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:['At "France Universit\xe9 Num\xe9rique", we deploy our applications on ',(0,t.jsx)(n.code,{children:"OpenShift"}),"/",(0,t.jsx)(n.code,{children:"Kubernetes"})," using\n",(0,t.jsx)(n.a,{href:"https://github.com/openfun/arnold",children:(0,t.jsx)(n.code,{children:"Arnold"})}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"getting-started",children:"Getting started"}),"\n",(0,t.jsx)(n.h3,{id:"docker",children:"Docker"}),"\n",(0,t.jsxs)(n.p,{children:["First, make sure you have a recent version of Docker and\n",(0,t.jsx)(n.a,{href:"https://docs.docker.com/compose/install",children:"Docker Compose"})," installed on your laptop:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ docker -v\n Docker version 1.13.1, build 092cba3\n\n$ docker-compose --version\n docker-compose version 1.17.1, build 6d101fb\n"})}),"\n",(0,t.jsxs)(n.p,{children:["\u26a0\ufe0f You may need to run the following commands with ",(0,t.jsx)(n.code,{children:"sudo"})," but this can be avoided by assigning your\nuser to the ",(0,t.jsx)(n.code,{children:"docker"})," group."]}),"\n",(0,t.jsx)(n.h3,{id:"project-bootstrap",children:"Project bootstrap"}),"\n",(0,t.jsxs)(n.p,{children:["The easiest way to start working on the project is to use our ",(0,t.jsx)(n.code,{children:"Makefile"}),":"]}),"\n",(0,t.jsx)(n.p,{children:"$ make bootstrap"}),"\n",(0,t.jsxs)(n.p,{children:["This command builds the ",(0,t.jsx)(n.code,{children:"app"})," container, installs front-end and back-end dependencies, builds the\nfront-end application and styles, and performs database migrations. It's a good idea to use this\ncommand each time you are pulling code from the project repository to avoid dependency-related or\nmigration-related issues."]}),"\n",(0,t.jsxs)(n.p,{children:["Now that your ",(0,t.jsx)(n.code,{children:"Docker"})," services are ready to be used, start the full CMS by running:"]}),"\n",(0,t.jsx)(n.p,{children:"$ make run"}),"\n",(0,t.jsx)(n.h3,{id:"adding-content",children:"Adding content"}),"\n",(0,t.jsx)(n.p,{children:"Once the CMS is up and running, you can create a superuser account:"}),"\n",(0,t.jsx)(n.p,{children:"$ make superuser"}),"\n",(0,t.jsx)(n.p,{children:"You can create a basic demo site by running:"}),"\n",(0,t.jsx)(n.p,{children:"$ make demo-site"}),"\n",(0,t.jsx)(n.p,{children:"Note that if you don't create the demo site and start from a blank CMS, you will get some errors\nrequesting you to create some required root pages. So it is easier as a first approach to test the\nCMS with the demo site."}),"\n",(0,t.jsxs)(n.p,{children:["You should be able to view the site at ",(0,t.jsx)(n.a,{href:"http://localhost:8070",children:"localhost:8070"})]}),"\n",(0,t.jsx)(n.h3,{id:"basic---connecting-richie-to-openedx",children:"Basic - Connecting Richie to OpenEdx"}),"\n",(0,t.jsxs)(n.p,{children:["This project is pre-configured to connect with an OpenEdx instance started with\n[OpenEdx Docker](",(0,t.jsx)(n.a,{href:"https://github.com/openfun/openedx-docker",children:"https://github.com/openfun/openedx-docker"}),"], which provides a ready to use\ndocker-compose stack of OpenEdx in several flavors. Head over to\n",(0,t.jsx)(n.a,{href:"https://github.com/openfun/openedx-docker#readme",children:"OpenEdx Docker README"})," for instructions on how\nto bootstrap an instance."]}),"\n",(0,t.jsxs)(n.p,{children:["Just start apps with ",(0,t.jsx)(n.code,{children:"make run"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Richie should respond on ",(0,t.jsx)(n.code,{children:"http://localhost:8070"})," and OpenEdx on ",(0,t.jsx)(n.code,{children:"http://localhost:8073"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"advanced---connecting-richie-to-openedx",children:"Advanced - Connecting Richie to OpenEdx"}),"\n",(0,t.jsxs)(n.p,{children:["If you want users to enroll on courses in OpenEdx directly from Richie via API calls, you should\nread ",(0,t.jsx)(n.a,{href:"/docs/2.3.1/lms-connection#connecting-richie-and-openedx-over-tls",children:"the advanced guide"})," to connect\nRichie to OpenEdx over TLS."]})]})}function h(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},11151:(e,n,o)=>{o.d(n,{Z:()=>c,a:()=>r});var t=o(67294);const i={},s=t.createContext(i);function r(e){const n=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),t.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/03e479ab.13f98885.js b/assets/js/03e479ab.13f98885.js new file mode 100644 index 0000000000..df4dad5268 --- /dev/null +++ b/assets/js/03e479ab.13f98885.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[92990],{19875:(n,e,i)=>{i.r(e),i.d(e,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>s,toc:()=>d});var t=i(85893),o=i(11151);const a={id:"internationalization",title:"Internationalization",sidebar_label:"I18n"},r=void 0,s={id:"internationalization",title:"Internationalization",description:"richie has built-in localization and internationalization:",source:"@site/versioned_docs/version-2.14.1/internationalization.md",sourceDirName:".",slug:"/internationalization",permalink:"/docs/2.14.1/internationalization",draft:!1,unlisted:!1,tags:[],version:"2.14.1",lastUpdatedBy:"Mehdi Benadda",lastUpdatedAt:1655108611e3,frontMatter:{id:"internationalization",title:"Internationalization",sidebar_label:"I18n"},sidebar:"docs",previous:{title:"Building the frontend",permalink:"/docs/2.14.1/building-the-frontend"},next:{title:"Frontend overrides",permalink:"/docs/2.14.1/frontend-overrides"}},c={},d=[{value:"Contributing as a translator or proof-reader",id:"contributing-as-a-translator-or-proof-reader",level:2},{value:"Sign-up on Crowdin",id:"sign-up-on-crowdin",level:3},{value:"Join the Richie project",id:"join-the-richie-project",level:3},{value:"Add a new language",id:"add-a-new-language",level:3}];function l(n){const e={a:"a",code:"code",h2:"h2",h3:"h3",img:"img",li:"li",p:"p",ul:"ul",...(0,o.a)(),...n.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:"richie"})," has built-in localization and internationalization:"]}),"\n",(0,t.jsxs)(e.ul,{children:["\n",(0,t.jsx)(e.li,{children:"On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,"}),"\n",(0,t.jsx)(e.li,{children:"On the frontend, we use React Intl."}),"\n"]}),"\n",(0,t.jsx)(e.h2,{id:"contributing-as-a-translator-or-proof-reader",children:"Contributing as a translator or proof-reader"}),"\n",(0,t.jsxs)(e.p,{children:["We use the ",(0,t.jsx)(e.a,{href:"https://crowdin.com",children:"Crowdin"})," web platform to translate Richie to different languages.\nAll translations are hosted at ",(0,t.jsx)(e.a,{href:"https://i18n.richie.education",children:"https://i18n.richie.education"}),", which allows translators and\nproof-readers to contribute on translations in the languages they master."]}),"\n",(0,t.jsx)(e.h3,{id:"sign-up-on-crowdin",children:"Sign-up on Crowdin"}),"\n",(0,t.jsxs)(e.p,{children:["If you don't have an account on Crowdin already, go to ",(0,t.jsx)(e.a,{href:"https://accounts.crowdin.com/register",children:"https://accounts.crowdin.com/register"})," and\nfill out the form to create a free account."]}),"\n",(0,t.jsx)(e.h3,{id:"join-the-richie-project",children:"Join the Richie project"}),"\n",(0,t.jsxs)(e.p,{children:["Now that you have an account on Crowdin,\n",(0,t.jsx)(e.a,{href:"https://crowdin.com/project/richie",children:'look for the project called "Richie"'}),', select the language\non which you wish to contribute and click the "Join" button as demonstrated below:']}),"\n",(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{alt:"How to join Richie on Crowdin",src:i(56152).Z+"",width:"2462",height:"1506"})}),"\n",(0,t.jsx)(e.p,{children:"We will then review you application and you should soon start translating strings!"}),"\n",(0,t.jsxs)(e.p,{children:["For more information on how Crowdin works, you can refer to\n",(0,t.jsx)(e.a,{href:"https://support.crowdin.com",children:"their documentation"}),"."]}),"\n",(0,t.jsx)(e.h3,{id:"add-a-new-language",children:"Add a new language"}),"\n",(0,t.jsxs)(e.p,{children:['If Richie is not yet translated in the language you want, let us know by clicking the "contact"\nlink on ',(0,t.jsx)(e.a,{href:"https://i18n.richie.education",children:"Richie's Crowdin profile page"})," and we will consider adding\nit."]}),"\n",(0,t.jsx)(e.p,{children:"If you request a new language, the Richie community will expect you to keep this language\nup-to-date each time strings are modified or new strings are added, and this before each\nrelease."}),"\n",(0,t.jsx)(e.p,{children:"Before asking for a new language, make sure it does not already exist. If your language already\nexists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider\ncontributing on the existing language if your resources to contribute are limited."})]})}function h(n={}){const{wrapper:e}={...(0,o.a)(),...n.components};return e?(0,t.jsx)(e,{...n,children:(0,t.jsx)(l,{...n})}):l(n)}},56152:(n,e,i)=>{i.d(e,{Z:()=>t});const t=i.p+"assets/images/crowdin-join-richie-fd505b1a132bafb2bdafc715649a7c0f.gif"},11151:(n,e,i)=>{i.d(e,{Z:()=>s,a:()=>r});var t=i(67294);const o={},a=t.createContext(o);function r(n){const e=t.useContext(a);return t.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function s(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(o):n.components||o:r(n.components),t.createElement(a.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/03e479ab.c258e004.js b/assets/js/03e479ab.c258e004.js deleted file mode 100644 index f9cceb843a..0000000000 --- a/assets/js/03e479ab.c258e004.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[92990],{19875:(n,e,t)=>{t.r(e),t.d(e,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>s,toc:()=>c});var i=t(85893),o=t(11151);const a={id:"internationalization",title:"Internationalization",sidebar_label:"I18n"},r=void 0,s={id:"internationalization",title:"Internationalization",description:"richie has built-in localization and internationalization:",source:"@site/versioned_docs/version-2.14.1/internationalization.md",sourceDirName:".",slug:"/internationalization",permalink:"/docs/2.14.1/internationalization",draft:!1,unlisted:!1,tags:[],version:"2.14.1",lastUpdatedBy:"Mehdi Benadda",lastUpdatedAt:1655108611,formattedLastUpdatedAt:"Jun 13, 2022",frontMatter:{id:"internationalization",title:"Internationalization",sidebar_label:"I18n"},sidebar:"docs",previous:{title:"Building the frontend",permalink:"/docs/2.14.1/building-the-frontend"},next:{title:"Frontend overrides",permalink:"/docs/2.14.1/frontend-overrides"}},d={},c=[{value:"Contributing as a translator or proof-reader",id:"contributing-as-a-translator-or-proof-reader",level:2},{value:"Sign-up on Crowdin",id:"sign-up-on-crowdin",level:3},{value:"Join the Richie project",id:"join-the-richie-project",level:3},{value:"Add a new language",id:"add-a-new-language",level:3}];function l(n){const e={a:"a",code:"code",h2:"h2",h3:"h3",img:"img",li:"li",p:"p",ul:"ul",...(0,o.a)(),...n.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(e.p,{children:[(0,i.jsx)(e.code,{children:"richie"})," has built-in localization and internationalization:"]}),"\n",(0,i.jsxs)(e.ul,{children:["\n",(0,i.jsx)(e.li,{children:"On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,"}),"\n",(0,i.jsx)(e.li,{children:"On the frontend, we use React Intl."}),"\n"]}),"\n",(0,i.jsx)(e.h2,{id:"contributing-as-a-translator-or-proof-reader",children:"Contributing as a translator or proof-reader"}),"\n",(0,i.jsxs)(e.p,{children:["We use the ",(0,i.jsx)(e.a,{href:"https://crowdin.com",children:"Crowdin"})," web platform to translate Richie to different languages.\nAll translations are hosted at ",(0,i.jsx)(e.a,{href:"https://i18n.richie.education",children:"https://i18n.richie.education"}),", which allows translators and\nproof-readers to contribute on translations in the languages they master."]}),"\n",(0,i.jsx)(e.h3,{id:"sign-up-on-crowdin",children:"Sign-up on Crowdin"}),"\n",(0,i.jsxs)(e.p,{children:["If you don't have an account on Crowdin already, go to ",(0,i.jsx)(e.a,{href:"https://accounts.crowdin.com/register",children:"https://accounts.crowdin.com/register"})," and\nfill out the form to create a free account."]}),"\n",(0,i.jsx)(e.h3,{id:"join-the-richie-project",children:"Join the Richie project"}),"\n",(0,i.jsxs)(e.p,{children:["Now that you have an account on Crowdin,\n",(0,i.jsx)(e.a,{href:"https://crowdin.com/project/richie",children:'look for the project called "Richie"'}),', select the language\non which you wish to contribute and click the "Join" button as demonstrated below:']}),"\n",(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{alt:"How to join Richie on Crowdin",src:t(56152).Z+"",width:"2462",height:"1506"})}),"\n",(0,i.jsx)(e.p,{children:"We will then review you application and you should soon start translating strings!"}),"\n",(0,i.jsxs)(e.p,{children:["For more information on how Crowdin works, you can refer to\n",(0,i.jsx)(e.a,{href:"https://support.crowdin.com",children:"their documentation"}),"."]}),"\n",(0,i.jsx)(e.h3,{id:"add-a-new-language",children:"Add a new language"}),"\n",(0,i.jsxs)(e.p,{children:['If Richie is not yet translated in the language you want, let us know by clicking the "contact"\nlink on ',(0,i.jsx)(e.a,{href:"https://i18n.richie.education",children:"Richie's Crowdin profile page"})," and we will consider adding\nit."]}),"\n",(0,i.jsx)(e.p,{children:"If you request a new language, the Richie community will expect you to keep this language\nup-to-date each time strings are modified or new strings are added, and this before each\nrelease."}),"\n",(0,i.jsx)(e.p,{children:"Before asking for a new language, make sure it does not already exist. If your language already\nexists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider\ncontributing on the existing language if your resources to contribute are limited."})]})}function h(n={}){const{wrapper:e}={...(0,o.a)(),...n.components};return e?(0,i.jsx)(e,{...n,children:(0,i.jsx)(l,{...n})}):l(n)}},56152:(n,e,t)=>{t.d(e,{Z:()=>i});const i=t.p+"assets/images/crowdin-join-richie-fd505b1a132bafb2bdafc715649a7c0f.gif"},11151:(n,e,t)=>{t.d(e,{Z:()=>s,a:()=>r});var i=t(67294);const o={},a=i.createContext(o);function r(n){const e=i.useContext(a);return i.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function s(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(o):n.components||o:r(n.components),i.createElement(a.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/05054f56.65f6d618.js b/assets/js/05054f56.65f6d618.js deleted file mode 100644 index 52caf90067..0000000000 --- a/assets/js/05054f56.65f6d618.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[51573],{15940:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>l,toc:()=>d});var s=t(85893),i=t(11151);const a={id:"native-installation",title:"Installing Richie on your machine",sidebar_label:"Native installation"},r=void 0,l={id:"native-installation",title:"Installing Richie on your machine",description:"This document aims to list all needed steps to have a working Richie",source:"@site/versioned_docs/version-2.3.0/native-installation.md",sourceDirName:".",slug:"/native-installation",permalink:"/docs/2.3.0/native-installation",draft:!1,unlisted:!1,tags:[],version:"2.3.0",lastUpdatedBy:"Mehdi Benadda",lastUpdatedAt:1655108611,formattedLastUpdatedAt:"Jun 13, 2022",frontMatter:{id:"native-installation",title:"Installing Richie on your machine",sidebar_label:"Native installation"},sidebar:"docs",previous:{title:"Docker development",permalink:"/docs/2.3.0/docker-development"},next:{title:"Django & React",permalink:"/docs/2.3.0/django-react-interop"}},o={},d=[{value:"Installing a fresh server",id:"installing-a-fresh-server",level:2},{value:"Version",id:"version",level:3},{value:"System update",id:"system-update",level:3},{value:"Database part",id:"database-part",level:2},{value:"Elasticsearch",id:"elasticsearch",level:2},{value:"Ubuntu",id:"ubuntu",level:3},{value:"OS X",id:"os-x",level:3},{value:"Application part",id:"application-part",level:2},{value:"Python and other requirements",id:"python-and-other-requirements",level:3},{value:"The virtualenv",id:"the-virtualenv",level:3},{value:"Frontend build",id:"frontend-build",level:3},{value:"Run server",id:"run-server",level:3}];function c(e){const n={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(n.p,{children:["This document aims to list all needed steps to have a working ",(0,s.jsx)(n.code,{children:"Richie"}),"\ninstallation on your laptop."]}),"\n",(0,s.jsxs)(n.p,{children:["A better approach is to use ",(0,s.jsx)(n.a,{href:"https://docs.docker.com",children:(0,s.jsx)(n.code,{children:"Docker"})})," as explained in\nour guide for ",(0,s.jsx)(n.a,{href:"/docs/2.3.0/discover",children:"container-native"})," instructions."]}),"\n",(0,s.jsx)(n.h2,{id:"installing-a-fresh-server",children:"Installing a fresh server"}),"\n",(0,s.jsx)(n.h3,{id:"version",children:"Version"}),"\n",(0,s.jsxs)(n.p,{children:["You need a ",(0,s.jsx)(n.code,{children:"Ubuntu 18.04 Bionic Beaver"})," (the latest LTS version) fresh\ninstallation."]}),"\n",(0,s.jsxs)(n.p,{children:["If you are using another operating system or distribution, you can use\n",(0,s.jsx)(n.a,{href:"https://docs.vagrantup.com/v2/getting-started/index.html",children:(0,s.jsx)(n.code,{children:"Vagrant"})})," to get a\nrunning Ubuntu 18.04 server in seconds."]}),"\n",(0,s.jsx)(n.h3,{id:"system-update",children:"System update"}),"\n",(0,s.jsx)(n.p,{children:"Be sure to have fresh packages on the server (kernel, libc, ssl patches...):\npost"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"sudo apt-get -y update\nsudo apt-get -y dist-upgrade\n"})}),"\n",(0,s.jsx)(n.h2,{id:"database-part",children:"Database part"}),"\n",(0,s.jsxs)(n.p,{children:["You must first install ",(0,s.jsx)(n.code,{children:"postgresql"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"// On Linux\nsudo apt-get -y install postgresql\n\n// On OS X\nbrew install postgresql@10\nbrew services start postgresql@10\n// don't forget to add your new postgres install to the $PATH\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Postgresql"})," is now running."]}),"\n",(0,s.jsxs)(n.p,{children:["Then you can create the database owner and the database itself, using the\n",(0,s.jsx)(n.code,{children:"postgres"})," user:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"sudo -u postgres -i // skip this on OS X as the default install will use your local user\ncreateuser fun -sP\n"})}),"\n",(0,s.jsx)(n.p,{children:"Note: we created the user as a superuser. This should only be done in dev/test\nenvironments."}),"\n",(0,s.jsx)(n.p,{children:"Now, create the database with this user:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"createdb richie -O fun -W\nexit\n"})}),"\n",(0,s.jsx)(n.h2,{id:"elasticsearch",children:"Elasticsearch"}),"\n",(0,s.jsx)(n.h3,{id:"ubuntu",children:"Ubuntu"}),"\n",(0,s.jsx)(n.p,{children:"Download and install the Public Signing Key"}),"\n",(0,s.jsxs)(n.p,{children:["$ wget -qO - ",(0,s.jsx)(n.a,{href:"https://artifacts.elastic.co/GPG-KEY-elasticsearch",children:"https://artifacts.elastic.co/GPG-KEY-elasticsearch"})," | sudo apt-key add -"]}),"\n",(0,s.jsx)(n.p,{children:"You may need to install the apt-transport-https package on Debian before\nproceeding:"}),"\n",(0,s.jsx)(n.p,{children:"$ sudo apt-get install apt-transport-https"}),"\n",(0,s.jsx)(n.p,{children:"Save the repository definition to /etc/apt/sources.list.d/elastic-6.3.1.list:"}),"\n",(0,s.jsxs)(n.p,{children:['$ echo "deb ',(0,s.jsx)(n.a,{href:"https://artifacts.elastic.co/packages/6.3.1/apt",children:"https://artifacts.elastic.co/packages/6.3.1/apt"}),' stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-6.3.1.list']}),"\n",(0,s.jsx)(n.p,{children:"Update repository and install"}),"\n",(0,s.jsx)(n.p,{children:"$ sudo apt-get update\n$ sudo apt-get install elasticsearch\n$ sudo /etc/init.d/elasticsearch start"}),"\n",(0,s.jsx)(n.h3,{id:"os-x",children:"OS X"}),"\n",(0,s.jsx)(n.p,{children:"$ brew install elasticsearch"}),"\n",(0,s.jsx)(n.h2,{id:"application-part",children:"Application part"}),"\n",(0,s.jsx)(n.h3,{id:"python-and-other-requirements",children:"Python and other requirements"}),"\n",(0,s.jsxs)(n.p,{children:["We use ",(0,s.jsx)(n.code,{children:"Python 3.6"})," which is the one installed by default in ",(0,s.jsx)(n.code,{children:"Ubuntu 18.04"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["You can install it on OS X using the following commands. Make sure to always run\n",(0,s.jsx)(n.code,{children:"python3"})," instead of ",(0,s.jsx)(n.code,{children:"python"})," and ",(0,s.jsx)(n.code,{children:"pip3"})," instead of ",(0,s.jsx)(n.code,{children:"pip"})," to ensure the correct\nversion of Python (your homebrew install of 3) is used."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"brew install python3\nbrew postinstall python3\n"})}),"\n",(0,s.jsx)(n.h3,{id:"the-virtualenv",children:"The virtualenv"}),"\n",(0,s.jsxs)(n.p,{children:["Place yourself in the application directory ",(0,s.jsx)(n.code,{children:"app"}),":"]}),"\n",(0,s.jsx)(n.p,{children:"cd app"}),"\n",(0,s.jsx)(n.p,{children:"We choose to run our application in a virtual environment."}),"\n",(0,s.jsxs)(n.p,{children:["For this, we'll install ",(0,s.jsx)(n.code,{children:"virtualenvwrapper"})," and add an environment:"]}),"\n",(0,s.jsx)(n.p,{children:"pip install virtualenvwrapper"}),"\n",(0,s.jsx)(n.p,{children:"You can open a new shell to activate the virtualenvwrapper commands, or simply\ndo:"}),"\n",(0,s.jsx)(n.p,{children:"source $(which virtualenvwrapper.sh)"}),"\n",(0,s.jsxs)(n.p,{children:["Then create the virtual environment for ",(0,s.jsx)(n.code,{children:"richie"}),":"]}),"\n",(0,s.jsx)(n.p,{children:"mkvirtualenv richie --no-site-packages --python=python3"}),"\n",(0,s.jsx)(n.p,{children:"The virtualenv should now be activated and you can install the Python\ndependencies for development:"}),"\n",(0,s.jsx)(n.p,{children:"pip install -e .[dev]"}),"\n",(0,s.jsx)(n.p,{children:'The "dev.txt" requirement file installs packages specific to a dev environment\nand should not be used in production.'}),"\n",(0,s.jsx)(n.h3,{id:"frontend-build",children:"Frontend build"}),"\n",(0,s.jsx)(n.p,{children:"This project is a hybrid that uses both Django generated pages and frontend JS\ncode. As such, it includes a frontend build process that comes in two parts: JS\n& CSS."}),"\n",(0,s.jsxs)(n.p,{children:["We need NPM to install the dependencies and run the build, which depends on a\nversion of Nodejs specified in ",(0,s.jsx)(n.code,{children:".nvmrc"}),". See ",(0,s.jsx)(n.a,{href:"https://github.com/creationix/nvm",children:"the\nrepo"})," for instructions on how to install NVM.\nTo take advantage of ",(0,s.jsx)(n.code,{children:".nvmrc"}),", run this in the context of the repository:"]}),"\n",(0,s.jsx)(n.p,{children:"nvm install\nnvm use"}),"\n",(0,s.jsxs)(n.p,{children:["As a prerequisite to running the frontend build for either JS or CSS, you'll\nneed to ",(0,s.jsx)(n.a,{href:"https://yarnpkg.com/lang/en/docs/install/",children:"install yarn"})," and download\ndependencies ",(0,s.jsx)(n.em,{children:"via"}),":"]}),"\n",(0,s.jsx)(n.p,{children:"yarn install"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"JS build"}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"npm run build\n"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"CSS build"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"This will compile all our SCSS files into one bundle and put it in the static\nfolder we're serving."}),"\n",(0,s.jsx)(n.p,{children:"npm run sass"}),"\n",(0,s.jsx)(n.h3,{id:"run-server",children:"Run server"}),"\n",(0,s.jsx)(n.p,{children:"Make sure your database is up-to-date before running the application the first\ntime and after each modification to your models:"}),"\n",(0,s.jsx)(n.p,{children:"python sandbox/manage.py migrate"}),"\n",(0,s.jsx)(n.p,{children:"You can create a superuser account:"}),"\n",(0,s.jsx)(n.p,{children:"python sandbox/manage.py createsuperuser"}),"\n",(0,s.jsx)(n.p,{children:"Run the tests"}),"\n",(0,s.jsx)(n.p,{children:"python sandbox/manage.py test"}),"\n",(0,s.jsxs)(n.p,{children:["You should now be able to start Django and view the site at\n",(0,s.jsx)(n.a,{href:"http://localhost:8000",children:"localhost:8000"})]}),"\n",(0,s.jsx)(n.p,{children:"python sandbox/manage.py runserver"})]})}function h(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},11151:(e,n,t)=>{t.d(n,{Z:()=>l,a:()=>r});var s=t(67294);const i={},a=s.createContext(i);function r(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/05054f56.79ea3f6b.js b/assets/js/05054f56.79ea3f6b.js new file mode 100644 index 0000000000..e6baf286a7 --- /dev/null +++ b/assets/js/05054f56.79ea3f6b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[51573],{15940:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>l,toc:()=>d});var s=t(85893),i=t(11151);const a={id:"native-installation",title:"Installing Richie on your machine",sidebar_label:"Native installation"},r=void 0,l={id:"native-installation",title:"Installing Richie on your machine",description:"This document aims to list all needed steps to have a working Richie",source:"@site/versioned_docs/version-2.3.0/native-installation.md",sourceDirName:".",slug:"/native-installation",permalink:"/docs/2.3.0/native-installation",draft:!1,unlisted:!1,tags:[],version:"2.3.0",lastUpdatedBy:"Mehdi Benadda",lastUpdatedAt:1655108611e3,frontMatter:{id:"native-installation",title:"Installing Richie on your machine",sidebar_label:"Native installation"},sidebar:"docs",previous:{title:"Docker development",permalink:"/docs/2.3.0/docker-development"},next:{title:"Django & React",permalink:"/docs/2.3.0/django-react-interop"}},o={},d=[{value:"Installing a fresh server",id:"installing-a-fresh-server",level:2},{value:"Version",id:"version",level:3},{value:"System update",id:"system-update",level:3},{value:"Database part",id:"database-part",level:2},{value:"Elasticsearch",id:"elasticsearch",level:2},{value:"Ubuntu",id:"ubuntu",level:3},{value:"OS X",id:"os-x",level:3},{value:"Application part",id:"application-part",level:2},{value:"Python and other requirements",id:"python-and-other-requirements",level:3},{value:"The virtualenv",id:"the-virtualenv",level:3},{value:"Frontend build",id:"frontend-build",level:3},{value:"Run server",id:"run-server",level:3}];function c(e){const n={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(n.p,{children:["This document aims to list all needed steps to have a working ",(0,s.jsx)(n.code,{children:"Richie"}),"\ninstallation on your laptop."]}),"\n",(0,s.jsxs)(n.p,{children:["A better approach is to use ",(0,s.jsx)(n.a,{href:"https://docs.docker.com",children:(0,s.jsx)(n.code,{children:"Docker"})})," as explained in\nour guide for ",(0,s.jsx)(n.a,{href:"/docs/2.3.0/discover",children:"container-native"})," instructions."]}),"\n",(0,s.jsx)(n.h2,{id:"installing-a-fresh-server",children:"Installing a fresh server"}),"\n",(0,s.jsx)(n.h3,{id:"version",children:"Version"}),"\n",(0,s.jsxs)(n.p,{children:["You need a ",(0,s.jsx)(n.code,{children:"Ubuntu 18.04 Bionic Beaver"})," (the latest LTS version) fresh\ninstallation."]}),"\n",(0,s.jsxs)(n.p,{children:["If you are using another operating system or distribution, you can use\n",(0,s.jsx)(n.a,{href:"https://docs.vagrantup.com/v2/getting-started/index.html",children:(0,s.jsx)(n.code,{children:"Vagrant"})})," to get a\nrunning Ubuntu 18.04 server in seconds."]}),"\n",(0,s.jsx)(n.h3,{id:"system-update",children:"System update"}),"\n",(0,s.jsx)(n.p,{children:"Be sure to have fresh packages on the server (kernel, libc, ssl patches...):\npost"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"sudo apt-get -y update\nsudo apt-get -y dist-upgrade\n"})}),"\n",(0,s.jsx)(n.h2,{id:"database-part",children:"Database part"}),"\n",(0,s.jsxs)(n.p,{children:["You must first install ",(0,s.jsx)(n.code,{children:"postgresql"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"// On Linux\nsudo apt-get -y install postgresql\n\n// On OS X\nbrew install postgresql@10\nbrew services start postgresql@10\n// don't forget to add your new postgres install to the $PATH\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Postgresql"})," is now running."]}),"\n",(0,s.jsxs)(n.p,{children:["Then you can create the database owner and the database itself, using the\n",(0,s.jsx)(n.code,{children:"postgres"})," user:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"sudo -u postgres -i // skip this on OS X as the default install will use your local user\ncreateuser fun -sP\n"})}),"\n",(0,s.jsx)(n.p,{children:"Note: we created the user as a superuser. This should only be done in dev/test\nenvironments."}),"\n",(0,s.jsx)(n.p,{children:"Now, create the database with this user:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"createdb richie -O fun -W\nexit\n"})}),"\n",(0,s.jsx)(n.h2,{id:"elasticsearch",children:"Elasticsearch"}),"\n",(0,s.jsx)(n.h3,{id:"ubuntu",children:"Ubuntu"}),"\n",(0,s.jsx)(n.p,{children:"Download and install the Public Signing Key"}),"\n",(0,s.jsxs)(n.p,{children:["$ wget -qO - ",(0,s.jsx)(n.a,{href:"https://artifacts.elastic.co/GPG-KEY-elasticsearch",children:"https://artifacts.elastic.co/GPG-KEY-elasticsearch"})," | sudo apt-key add -"]}),"\n",(0,s.jsx)(n.p,{children:"You may need to install the apt-transport-https package on Debian before\nproceeding:"}),"\n",(0,s.jsx)(n.p,{children:"$ sudo apt-get install apt-transport-https"}),"\n",(0,s.jsx)(n.p,{children:"Save the repository definition to /etc/apt/sources.list.d/elastic-6.3.1.list:"}),"\n",(0,s.jsxs)(n.p,{children:['$ echo "deb ',(0,s.jsx)(n.a,{href:"https://artifacts.elastic.co/packages/6.3.1/apt",children:"https://artifacts.elastic.co/packages/6.3.1/apt"}),' stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-6.3.1.list']}),"\n",(0,s.jsx)(n.p,{children:"Update repository and install"}),"\n",(0,s.jsx)(n.p,{children:"$ sudo apt-get update\n$ sudo apt-get install elasticsearch\n$ sudo /etc/init.d/elasticsearch start"}),"\n",(0,s.jsx)(n.h3,{id:"os-x",children:"OS X"}),"\n",(0,s.jsx)(n.p,{children:"$ brew install elasticsearch"}),"\n",(0,s.jsx)(n.h2,{id:"application-part",children:"Application part"}),"\n",(0,s.jsx)(n.h3,{id:"python-and-other-requirements",children:"Python and other requirements"}),"\n",(0,s.jsxs)(n.p,{children:["We use ",(0,s.jsx)(n.code,{children:"Python 3.6"})," which is the one installed by default in ",(0,s.jsx)(n.code,{children:"Ubuntu 18.04"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["You can install it on OS X using the following commands. Make sure to always run\n",(0,s.jsx)(n.code,{children:"python3"})," instead of ",(0,s.jsx)(n.code,{children:"python"})," and ",(0,s.jsx)(n.code,{children:"pip3"})," instead of ",(0,s.jsx)(n.code,{children:"pip"})," to ensure the correct\nversion of Python (your homebrew install of 3) is used."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"brew install python3\nbrew postinstall python3\n"})}),"\n",(0,s.jsx)(n.h3,{id:"the-virtualenv",children:"The virtualenv"}),"\n",(0,s.jsxs)(n.p,{children:["Place yourself in the application directory ",(0,s.jsx)(n.code,{children:"app"}),":"]}),"\n",(0,s.jsx)(n.p,{children:"cd app"}),"\n",(0,s.jsx)(n.p,{children:"We choose to run our application in a virtual environment."}),"\n",(0,s.jsxs)(n.p,{children:["For this, we'll install ",(0,s.jsx)(n.code,{children:"virtualenvwrapper"})," and add an environment:"]}),"\n",(0,s.jsx)(n.p,{children:"pip install virtualenvwrapper"}),"\n",(0,s.jsx)(n.p,{children:"You can open a new shell to activate the virtualenvwrapper commands, or simply\ndo:"}),"\n",(0,s.jsx)(n.p,{children:"source $(which virtualenvwrapper.sh)"}),"\n",(0,s.jsxs)(n.p,{children:["Then create the virtual environment for ",(0,s.jsx)(n.code,{children:"richie"}),":"]}),"\n",(0,s.jsx)(n.p,{children:"mkvirtualenv richie --no-site-packages --python=python3"}),"\n",(0,s.jsx)(n.p,{children:"The virtualenv should now be activated and you can install the Python\ndependencies for development:"}),"\n",(0,s.jsx)(n.p,{children:"pip install -e .[dev]"}),"\n",(0,s.jsx)(n.p,{children:'The "dev.txt" requirement file installs packages specific to a dev environment\nand should not be used in production.'}),"\n",(0,s.jsx)(n.h3,{id:"frontend-build",children:"Frontend build"}),"\n",(0,s.jsx)(n.p,{children:"This project is a hybrid that uses both Django generated pages and frontend JS\ncode. As such, it includes a frontend build process that comes in two parts: JS\n& CSS."}),"\n",(0,s.jsxs)(n.p,{children:["We need NPM to install the dependencies and run the build, which depends on a\nversion of Nodejs specified in ",(0,s.jsx)(n.code,{children:".nvmrc"}),". See ",(0,s.jsx)(n.a,{href:"https://github.com/creationix/nvm",children:"the\nrepo"})," for instructions on how to install NVM.\nTo take advantage of ",(0,s.jsx)(n.code,{children:".nvmrc"}),", run this in the context of the repository:"]}),"\n",(0,s.jsx)(n.p,{children:"nvm install\nnvm use"}),"\n",(0,s.jsxs)(n.p,{children:["As a prerequisite to running the frontend build for either JS or CSS, you'll\nneed to ",(0,s.jsx)(n.a,{href:"https://yarnpkg.com/lang/en/docs/install/",children:"install yarn"})," and download\ndependencies ",(0,s.jsx)(n.em,{children:"via"}),":"]}),"\n",(0,s.jsx)(n.p,{children:"yarn install"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"JS build"}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"npm run build\n"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"CSS build"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"This will compile all our SCSS files into one bundle and put it in the static\nfolder we're serving."}),"\n",(0,s.jsx)(n.p,{children:"npm run sass"}),"\n",(0,s.jsx)(n.h3,{id:"run-server",children:"Run server"}),"\n",(0,s.jsx)(n.p,{children:"Make sure your database is up-to-date before running the application the first\ntime and after each modification to your models:"}),"\n",(0,s.jsx)(n.p,{children:"python sandbox/manage.py migrate"}),"\n",(0,s.jsx)(n.p,{children:"You can create a superuser account:"}),"\n",(0,s.jsx)(n.p,{children:"python sandbox/manage.py createsuperuser"}),"\n",(0,s.jsx)(n.p,{children:"Run the tests"}),"\n",(0,s.jsx)(n.p,{children:"python sandbox/manage.py test"}),"\n",(0,s.jsxs)(n.p,{children:["You should now be able to start Django and view the site at\n",(0,s.jsx)(n.a,{href:"http://localhost:8000",children:"localhost:8000"})]}),"\n",(0,s.jsx)(n.p,{children:"python sandbox/manage.py runserver"})]})}function h(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},11151:(e,n,t)=>{t.d(n,{Z:()=>l,a:()=>r});var s=t(67294);const i={},a=s.createContext(i);function r(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/05adccc0.3f338ef6.js b/assets/js/05adccc0.3f338ef6.js new file mode 100644 index 0000000000..3c4f1ba124 --- /dev/null +++ b/assets/js/05adccc0.3f338ef6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[83798],{92438:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var o=s(85893),t=s(11151);const i={id:"installation",title:"Installing Richie for development",sidebar_label:"Installation"},r=void 0,c={id:"installation",title:"Installing Richie for development",description:"Richie is a container-native application but can also be installed",source:"@site/versioned_docs/version-2.20.0/installation.md",sourceDirName:".",slug:"/installation",permalink:"/docs/2.20.0/installation",draft:!1,unlisted:!1,tags:[],version:"2.20.0",lastUpdatedBy:"jbpenrath",lastUpdatedAt:1676647239e3,frontMatter:{id:"installation",title:"Installing Richie for development",sidebar_label:"Installation"},sidebar:"docs",previous:{title:"Web Analytics",permalink:"/docs/2.20.0/web-analytics"},next:{title:"Docker development",permalink:"/docs/2.20.0/docker-development"}},a={},l=[{value:"Docker",id:"docker",level:2},{value:"Project bootstrap",id:"project-bootstrap",level:3},{value:"Adding content",id:"adding-content",level:3},{value:"Connecting Richie to an LMS",id:"connecting-richie-to-an-lms",level:2}];function d(e){const n={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.a)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.code,{children:"Richie"})," is a ",(0,o.jsx)(n.strong,{children:"container-native application"})," but can also be installed\n",(0,o.jsx)(n.a,{href:"/docs/2.20.0/native-installation",children:"on your machine"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["For development, the project is defined using a\n",(0,o.jsx)(n.a,{href:"../docker-compose.yml",children:"docker-compose file"})," and consists of:"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"3 running services:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.strong,{children:"database"}),": ",(0,o.jsx)(n.code,{children:"postgresql"})," or ",(0,o.jsx)(n.code,{children:"mysql"})," at your preference,"]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.strong,{children:"elasticsearch"}),": the search engine,"]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.strong,{children:"app"}),": the actual ",(0,o.jsx)(n.code,{children:"DjangoCMS"})," project with all our application code."]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"2 containers for building purposes:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.strong,{children:"node"}),": used for front-end related tasks, ",(0,o.jsx)(n.em,{children:"i.e."})," transpiling\n",(0,o.jsx)(n.code,{children:"TypeScript"})," sources, bundling them into a JS package, and building the\nCSS files from Sass sources,"]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.strong,{children:"crowdin"}),": used to upload and retrieve i18n files to and from the\n",(0,o.jsx)(n.a,{href:"https://crowdin.com/",children:"Crowding"})," service that we use to crowd source\ntranslations,"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:['At "France Universit\xe9 Num\xe9rique", we deploy our applications on ',(0,o.jsx)(n.code,{children:"Kubernetes"}),"\nusing ",(0,o.jsx)(n.a,{href:"https://github.com/openfun/arnold",children:(0,o.jsx)(n.code,{children:"Arnold"})}),"."]}),"\n",(0,o.jsx)(n.h2,{id:"docker",children:"Docker"}),"\n",(0,o.jsxs)(n.p,{children:["First, make sure you have a recent version of Docker and\n",(0,o.jsx)(n.a,{href:"https://docs.docker.com/compose/install",children:"Docker Compose"})," installed on your\nlaptop:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"$ docker -v\n Docker version 20.10.12, build e91ed57\n\n$ docker-compose --version\n docker-compose version 1.29.2, build 5becea4c\n"})}),"\n",(0,o.jsxs)(n.p,{children:["\u26a0\ufe0f You may need to run the following commands with ",(0,o.jsx)(n.code,{children:"sudo"})," but this can be\navoided by assigning your user to the ",(0,o.jsx)(n.code,{children:"docker"})," group."]}),"\n",(0,o.jsx)(n.h3,{id:"project-bootstrap",children:"Project bootstrap"}),"\n",(0,o.jsxs)(n.p,{children:["The easiest way to start working on the project is to use our ",(0,o.jsx)(n.code,{children:"Makefile"}),":"]}),"\n",(0,o.jsx)(n.p,{children:"$ make bootstrap"}),"\n",(0,o.jsxs)(n.p,{children:["This command builds the ",(0,o.jsx)(n.code,{children:"app"})," container, installs front-end and back-end\ndependencies, builds the front-end application and styles, and performs\ndatabase migrations. It's a good idea to use this command each time you are\npulling code from the project repository to avoid dependency-related or\nmigration-related issues."]}),"\n",(0,o.jsxs)(n.p,{children:["Now that your ",(0,o.jsx)(n.code,{children:"Docker"})," services are ready to be used, start the full CMS by\nrunning:"]}),"\n",(0,o.jsx)(n.p,{children:"$ make run"}),"\n",(0,o.jsx)(n.h3,{id:"adding-content",children:"Adding content"}),"\n",(0,o.jsx)(n.p,{children:"Once the CMS is up and running, you can create a superuser account:"}),"\n",(0,o.jsx)(n.p,{children:"$ make superuser"}),"\n",(0,o.jsx)(n.p,{children:"You can create a basic demo site by running:"}),"\n",(0,o.jsx)(n.p,{children:"$ make demo-site"}),"\n",(0,o.jsx)(n.p,{children:"Note that if you don't create the demo site and start from a blank CMS, you\nwill get some errors requesting you to create some required root pages. So it\nis easier as a first approach to test the CMS with the demo site."}),"\n",(0,o.jsxs)(n.p,{children:["You should be able to view the site at ",(0,o.jsx)(n.a,{href:"http://localhost:8070",children:"localhost:8070"})]}),"\n",(0,o.jsx)(n.h2,{id:"connecting-richie-to-an-lms",children:"Connecting Richie to an LMS"}),"\n",(0,o.jsx)(n.p,{children:"It is possible to use Richie as a catalogue aggregating courses from one or\nmore LMS without any specific connection. In this case, each course run in\nthe catalogue points to a course on the LMS, and the LMS points back to the\ncatalogue to browse courses."}),"\n",(0,o.jsxs)(n.p,{children:["This approach is used for example on ",(0,o.jsx)(n.a,{href:"https://www.fun-campus.fr",children:"https://www.fun-campus.fr"})," or\n",(0,o.jsx)(n.a,{href:"https://catalogue.edulib.org",children:"https://catalogue.edulib.org"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["For a seamless user experience, it is possible to connect a Richie instance\nto an OpenEdX instance (or some other LMS like Moodle at the cost of minor\nadaptations), in several ways that we explain in the\n",(0,o.jsx)(n.a,{href:"lms-connection",children:"LMS connection guide"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["This approach is used for example on ",(0,o.jsx)(n.a,{href:"https://www.fun-mooc.fr",children:"https://www.fun-mooc.fr"})," or\n",(0,o.jsx)(n.a,{href:"https://www.nau.edu.pt",children:"https://www.nau.edu.pt"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,t.a)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},11151:(e,n,s)=>{s.d(n,{Z:()=>c,a:()=>r});var o=s(67294);const t={},i=o.createContext(t);function r(e){const n=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),o.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/05adccc0.f2de587c.js b/assets/js/05adccc0.f2de587c.js deleted file mode 100644 index 326d111318..0000000000 --- a/assets/js/05adccc0.f2de587c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[83798],{92438:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var t=s(85893),o=s(11151);const i={id:"installation",title:"Installing Richie for development",sidebar_label:"Installation"},r=void 0,c={id:"installation",title:"Installing Richie for development",description:"Richie is a container-native application but can also be installed",source:"@site/versioned_docs/version-2.20.0/installation.md",sourceDirName:".",slug:"/installation",permalink:"/docs/2.20.0/installation",draft:!1,unlisted:!1,tags:[],version:"2.20.0",lastUpdatedBy:"jbpenrath",lastUpdatedAt:1676647239,formattedLastUpdatedAt:"Feb 17, 2023",frontMatter:{id:"installation",title:"Installing Richie for development",sidebar_label:"Installation"},sidebar:"docs",previous:{title:"Web Analytics",permalink:"/docs/2.20.0/web-analytics"},next:{title:"Docker development",permalink:"/docs/2.20.0/docker-development"}},a={},l=[{value:"Docker",id:"docker",level:2},{value:"Project bootstrap",id:"project-bootstrap",level:3},{value:"Adding content",id:"adding-content",level:3},{value:"Connecting Richie to an LMS",id:"connecting-richie-to-an-lms",level:2}];function d(e){const n={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"Richie"})," is a ",(0,t.jsx)(n.strong,{children:"container-native application"})," but can also be installed\n",(0,t.jsx)(n.a,{href:"/docs/2.20.0/native-installation",children:"on your machine"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["For development, the project is defined using a\n",(0,t.jsx)(n.a,{href:"../docker-compose.yml",children:"docker-compose file"})," and consists of:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"3 running services:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"database"}),": ",(0,t.jsx)(n.code,{children:"postgresql"})," or ",(0,t.jsx)(n.code,{children:"mysql"})," at your preference,"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"elasticsearch"}),": the search engine,"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"app"}),": the actual ",(0,t.jsx)(n.code,{children:"DjangoCMS"})," project with all our application code."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"2 containers for building purposes:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"node"}),": used for front-end related tasks, ",(0,t.jsx)(n.em,{children:"i.e."})," transpiling\n",(0,t.jsx)(n.code,{children:"TypeScript"})," sources, bundling them into a JS package, and building the\nCSS files from Sass sources,"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"crowdin"}),": used to upload and retrieve i18n files to and from the\n",(0,t.jsx)(n.a,{href:"https://crowdin.com/",children:"Crowding"})," service that we use to crowd source\ntranslations,"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:['At "France Universit\xe9 Num\xe9rique", we deploy our applications on ',(0,t.jsx)(n.code,{children:"Kubernetes"}),"\nusing ",(0,t.jsx)(n.a,{href:"https://github.com/openfun/arnold",children:(0,t.jsx)(n.code,{children:"Arnold"})}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"docker",children:"Docker"}),"\n",(0,t.jsxs)(n.p,{children:["First, make sure you have a recent version of Docker and\n",(0,t.jsx)(n.a,{href:"https://docs.docker.com/compose/install",children:"Docker Compose"})," installed on your\nlaptop:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ docker -v\n Docker version 20.10.12, build e91ed57\n\n$ docker-compose --version\n docker-compose version 1.29.2, build 5becea4c\n"})}),"\n",(0,t.jsxs)(n.p,{children:["\u26a0\ufe0f You may need to run the following commands with ",(0,t.jsx)(n.code,{children:"sudo"})," but this can be\navoided by assigning your user to the ",(0,t.jsx)(n.code,{children:"docker"})," group."]}),"\n",(0,t.jsx)(n.h3,{id:"project-bootstrap",children:"Project bootstrap"}),"\n",(0,t.jsxs)(n.p,{children:["The easiest way to start working on the project is to use our ",(0,t.jsx)(n.code,{children:"Makefile"}),":"]}),"\n",(0,t.jsx)(n.p,{children:"$ make bootstrap"}),"\n",(0,t.jsxs)(n.p,{children:["This command builds the ",(0,t.jsx)(n.code,{children:"app"})," container, installs front-end and back-end\ndependencies, builds the front-end application and styles, and performs\ndatabase migrations. It's a good idea to use this command each time you are\npulling code from the project repository to avoid dependency-related or\nmigration-related issues."]}),"\n",(0,t.jsxs)(n.p,{children:["Now that your ",(0,t.jsx)(n.code,{children:"Docker"})," services are ready to be used, start the full CMS by\nrunning:"]}),"\n",(0,t.jsx)(n.p,{children:"$ make run"}),"\n",(0,t.jsx)(n.h3,{id:"adding-content",children:"Adding content"}),"\n",(0,t.jsx)(n.p,{children:"Once the CMS is up and running, you can create a superuser account:"}),"\n",(0,t.jsx)(n.p,{children:"$ make superuser"}),"\n",(0,t.jsx)(n.p,{children:"You can create a basic demo site by running:"}),"\n",(0,t.jsx)(n.p,{children:"$ make demo-site"}),"\n",(0,t.jsx)(n.p,{children:"Note that if you don't create the demo site and start from a blank CMS, you\nwill get some errors requesting you to create some required root pages. So it\nis easier as a first approach to test the CMS with the demo site."}),"\n",(0,t.jsxs)(n.p,{children:["You should be able to view the site at ",(0,t.jsx)(n.a,{href:"http://localhost:8070",children:"localhost:8070"})]}),"\n",(0,t.jsx)(n.h2,{id:"connecting-richie-to-an-lms",children:"Connecting Richie to an LMS"}),"\n",(0,t.jsx)(n.p,{children:"It is possible to use Richie as a catalogue aggregating courses from one or\nmore LMS without any specific connection. In this case, each course run in\nthe catalogue points to a course on the LMS, and the LMS points back to the\ncatalogue to browse courses."}),"\n",(0,t.jsxs)(n.p,{children:["This approach is used for example on ",(0,t.jsx)(n.a,{href:"https://www.fun-campus.fr",children:"https://www.fun-campus.fr"})," or\n",(0,t.jsx)(n.a,{href:"https://catalogue.edulib.org",children:"https://catalogue.edulib.org"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["For a seamless user experience, it is possible to connect a Richie instance\nto an OpenEdX instance (or some other LMS like Moodle at the cost of minor\nadaptations), in several ways that we explain in the\n",(0,t.jsx)(n.a,{href:"lms-connection",children:"LMS connection guide"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["This approach is used for example on ",(0,t.jsx)(n.a,{href:"https://www.fun-mooc.fr",children:"https://www.fun-mooc.fr"})," or\n",(0,t.jsx)(n.a,{href:"https://www.nau.edu.pt",children:"https://www.nau.edu.pt"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},11151:(e,n,s)=>{s.d(n,{Z:()=>c,a:()=>r});var t=s(67294);const o={},i=t.createContext(o);function r(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/061b9ec0.8578e0c1.js b/assets/js/061b9ec0.8578e0c1.js deleted file mode 100644 index 9913cbf57d..0000000000 --- a/assets/js/061b9ec0.8578e0c1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[74685],{89338:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>a,contentTitle:()=>r,default:()=>u,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var n=t(85893),o=t(11151);const i={id:"css-guidelines",title:"CSS Guidelines",sidebar_label:"CSS Guidelines"},r=void 0,l={id:"css-guidelines",title:"CSS Guidelines",description:"The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.",source:"@site/versioned_docs/version-2.21.1/css-guidelines.md",sourceDirName:".",slug:"/css-guidelines",permalink:"/docs/2.21.1/css-guidelines",draft:!1,unlisted:!1,tags:[],version:"2.21.1",lastUpdatedBy:"jbpenrath",lastUpdatedAt:1680624606,formattedLastUpdatedAt:"Apr 4, 2023",frontMatter:{id:"css-guidelines",title:"CSS Guidelines",sidebar_label:"CSS Guidelines"},sidebar:"docs",previous:{title:"Accessibility testing",permalink:"/docs/2.21.1/accessibility-testing"}},a={},c=[{value:"File structuration",id:"file-structuration",level:2},{value:"Code structuration",id:"code-structuration",level:2},{value:"Quick pointers",id:"quick-pointers",level:2}];function d(e){const s={a:"a",code:"code",em:"em",h2:"h2",li:"li",p:"p",strong:"strong",ul:"ul",...(0,o.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.p,{children:"The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly."}),"\n",(0,n.jsx)(s.p,{children:"Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations."}),"\n",(0,n.jsx)(s.h2,{id:"file-structuration",children:"File structuration"}),"\n",(0,n.jsx)(s.p,{children:"Rules should be placed where their purpose is most apparent, and where they are easiest to find."}),"\n",(0,n.jsxs)(s.p,{children:["Generally, this means CSS rules should live as close as possible to the place they are used. For example, the selectors and rules that define the look for a component should live in a ",(0,n.jsx)(s.code,{children:".scss"})," file in the same folder as the JS file for this component. This goes for templates too. Such files can only contain rules that are ",(0,n.jsx)(s.strong,{children:"specific to this component/template and this one only"})]}),"\n",(0,n.jsxs)(s.p,{children:["Only general base rules, utility rules, site layout rules as well as our custom variables should live in the central ",(0,n.jsx)(s.code,{children:"app/static/scss"})," folder."]}),"\n",(0,n.jsx)(s.h2,{id:"code-structuration",children:"Code structuration"}),"\n",(0,n.jsx)(s.p,{children:"In order to understand what classes are about at a glance and avoid collisions, naming conventions must be enforced for classes."}),"\n",(0,n.jsxs)(s.p,{children:["Following the ",(0,n.jsx)(s.a,{href:"http://getbem.com/introduction/",children:"BEM naming convention"}),", we will write our classes as follows :"]}),"\n",(0,n.jsxs)(s.p,{children:[".block ","\n.block__element ","\n.block--modifier "]}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:".block"})," represents the higher level of an abstraction or component."]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:".block__element"})," represents a descendent of .block that helps form .block as a whole."]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:".block--modifier"})," represents a different state or version of .block."]}),"\n"]}),"\n",(0,n.jsxs)(s.p,{children:["We use double hyphens and double underscores as delimiters so that names themselves can be hyphen-delimited (e.g. ",(0,n.jsx)(s.code,{children:".site-search__field--full"}),")."]}),"\n",(0,n.jsx)(s.p,{children:"Yes, this notation is ugly. However, it allows our classes to express what they are doing. Both our CSS and our markup become more meaningful. It allows us to easily see what classes are related to others, and how they are related, when we look at the markup."}),"\n",(0,n.jsx)(s.h2,{id:"quick-pointers",children:"Quick pointers"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:["In general, ",(0,n.jsx)(s.strong,{children:"do not use IDs"}),". ",(0,n.jsx)(s.em,{children:"They can cause specificity wars and are not supposed to be reusable, and are therefore not very useful."})]}),"\n",(0,n.jsxs)(s.li,{children:["Do not nest selectors unnecessarily. ",(0,n.jsx)(s.em,{children:"It will increase specificity and affect where else you can use your styles."})]}),"\n",(0,n.jsxs)(s.li,{children:["Do not qualify selectors unnecessarily. ",(0,n.jsx)(s.em,{children:"It will impact the number of different elements you can apply styles to."})]}),"\n",(0,n.jsxs)(s.li,{children:["Comment profusely, ",(0,n.jsx)(s.em,{children:"whenever you think the CSS is getting complex or it would not be easy to understand its intent."})]}),"\n",(0,n.jsxs)(s.li,{children:["Use !important proactively. ",(0,n.jsx)(s.em,{children:"!important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively."})]}),"\n"]}),"\n",(0,n.jsxs)(s.p,{children:["(Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. ",(0,n.jsx)(s.code,{children:"div > #example"})," is A LOT more efficient than ",(0,n.jsx)(s.code,{children:"#example > div"})," although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See ",(0,n.jsx)(s.a,{href:"http://csswizardry.com/2011/09/writing-efficient-css-selectors/",children:"CSS Wizardry"})," for more details."]})]})}function u(e={}){const{wrapper:s}={...(0,o.a)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},11151:(e,s,t)=>{t.d(s,{Z:()=>l,a:()=>r});var n=t(67294);const o={},i=n.createContext(o);function r(e){const s=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),n.createElement(i.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/061b9ec0.bba32130.js b/assets/js/061b9ec0.bba32130.js new file mode 100644 index 0000000000..dda1f1bc0c --- /dev/null +++ b/assets/js/061b9ec0.bba32130.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[74685],{89338:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>a,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var n=t(85893),i=t(11151);const o={id:"css-guidelines",title:"CSS Guidelines",sidebar_label:"CSS Guidelines"},r=void 0,l={id:"css-guidelines",title:"CSS Guidelines",description:"The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.",source:"@site/versioned_docs/version-2.21.1/css-guidelines.md",sourceDirName:".",slug:"/css-guidelines",permalink:"/docs/2.21.1/css-guidelines",draft:!1,unlisted:!1,tags:[],version:"2.21.1",lastUpdatedBy:"jbpenrath",lastUpdatedAt:1680624606e3,frontMatter:{id:"css-guidelines",title:"CSS Guidelines",sidebar_label:"CSS Guidelines"},sidebar:"docs",previous:{title:"Accessibility testing",permalink:"/docs/2.21.1/accessibility-testing"}},a={},c=[{value:"File structuration",id:"file-structuration",level:2},{value:"Code structuration",id:"code-structuration",level:2},{value:"Quick pointers",id:"quick-pointers",level:2}];function d(e){const s={a:"a",code:"code",em:"em",h2:"h2",li:"li",p:"p",strong:"strong",ul:"ul",...(0,i.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.p,{children:"The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly."}),"\n",(0,n.jsx)(s.p,{children:"Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations."}),"\n",(0,n.jsx)(s.h2,{id:"file-structuration",children:"File structuration"}),"\n",(0,n.jsx)(s.p,{children:"Rules should be placed where their purpose is most apparent, and where they are easiest to find."}),"\n",(0,n.jsxs)(s.p,{children:["Generally, this means CSS rules should live as close as possible to the place they are used. For example, the selectors and rules that define the look for a component should live in a ",(0,n.jsx)(s.code,{children:".scss"})," file in the same folder as the JS file for this component. This goes for templates too. Such files can only contain rules that are ",(0,n.jsx)(s.strong,{children:"specific to this component/template and this one only"})]}),"\n",(0,n.jsxs)(s.p,{children:["Only general base rules, utility rules, site layout rules as well as our custom variables should live in the central ",(0,n.jsx)(s.code,{children:"app/static/scss"})," folder."]}),"\n",(0,n.jsx)(s.h2,{id:"code-structuration",children:"Code structuration"}),"\n",(0,n.jsx)(s.p,{children:"In order to understand what classes are about at a glance and avoid collisions, naming conventions must be enforced for classes."}),"\n",(0,n.jsxs)(s.p,{children:["Following the ",(0,n.jsx)(s.a,{href:"http://getbem.com/introduction/",children:"BEM naming convention"}),", we will write our classes as follows :"]}),"\n",(0,n.jsxs)(s.p,{children:[".block ","\n.block__element ","\n.block--modifier "]}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:".block"})," represents the higher level of an abstraction or component."]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:".block__element"})," represents a descendent of .block that helps form .block as a whole."]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:".block--modifier"})," represents a different state or version of .block."]}),"\n"]}),"\n",(0,n.jsxs)(s.p,{children:["We use double hyphens and double underscores as delimiters so that names themselves can be hyphen-delimited (e.g. ",(0,n.jsx)(s.code,{children:".site-search__field--full"}),")."]}),"\n",(0,n.jsx)(s.p,{children:"Yes, this notation is ugly. However, it allows our classes to express what they are doing. Both our CSS and our markup become more meaningful. It allows us to easily see what classes are related to others, and how they are related, when we look at the markup."}),"\n",(0,n.jsx)(s.h2,{id:"quick-pointers",children:"Quick pointers"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:["In general, ",(0,n.jsx)(s.strong,{children:"do not use IDs"}),". ",(0,n.jsx)(s.em,{children:"They can cause specificity wars and are not supposed to be reusable, and are therefore not very useful."})]}),"\n",(0,n.jsxs)(s.li,{children:["Do not nest selectors unnecessarily. ",(0,n.jsx)(s.em,{children:"It will increase specificity and affect where else you can use your styles."})]}),"\n",(0,n.jsxs)(s.li,{children:["Do not qualify selectors unnecessarily. ",(0,n.jsx)(s.em,{children:"It will impact the number of different elements you can apply styles to."})]}),"\n",(0,n.jsxs)(s.li,{children:["Comment profusely, ",(0,n.jsx)(s.em,{children:"whenever you think the CSS is getting complex or it would not be easy to understand its intent."})]}),"\n",(0,n.jsxs)(s.li,{children:["Use !important proactively. ",(0,n.jsx)(s.em,{children:"!important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively."})]}),"\n"]}),"\n",(0,n.jsxs)(s.p,{children:["(Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. ",(0,n.jsx)(s.code,{children:"div > #example"})," is A LOT more efficient than ",(0,n.jsx)(s.code,{children:"#example > div"})," although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See ",(0,n.jsx)(s.a,{href:"http://csswizardry.com/2011/09/writing-efficient-css-selectors/",children:"CSS Wizardry"})," for more details."]})]})}function u(e={}){const{wrapper:s}={...(0,i.a)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},11151:(e,s,t)=>{t.d(s,{Z:()=>l,a:()=>r});var n=t(67294);const i={},o=n.createContext(i);function r(e){const s=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),n.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/06447dd5.3f895c02.js b/assets/js/06447dd5.3f895c02.js deleted file mode 100644 index 554938f52f..0000000000 --- a/assets/js/06447dd5.3f895c02.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[42814],{38178:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>a,toc:()=>d});var s=t(85893),i=t(11151);const o={id:"django-react-interop",title:"Connecting React components with Django",sidebar_label:"Django & React"},r=void 0,a={id:"django-react-interop",title:"Connecting React components with Django",description:"richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.",source:"@site/versioned_docs/version-2.23.0/django-react-interop.md",sourceDirName:".",slug:"/django-react-interop",permalink:"/docs/2.23.0/django-react-interop",draft:!1,unlisted:!1,tags:[],version:"2.23.0",lastUpdatedBy:"jbpenrath",lastUpdatedAt:1699548651,formattedLastUpdatedAt:"Nov 9, 2023",frontMatter:{id:"django-react-interop",title:"Connecting React components with Django",sidebar_label:"Django & React"},sidebar:"docs",previous:{title:"Search filters customization",permalink:"/docs/2.23.0/filters-customization"},next:{title:"Building the frontend",permalink:"/docs/2.23.0/building-the-frontend"}},c={},d=[{value:"Rendering components",id:"rendering-components",level:2},{value:"Example",id:"example",level:3},{value:"Passing properties to components",id:"passing-properties-to-components",level:2},{value:"Example",id:"example-1",level:3},{value:"Built-in components",id:"built-in-components",level:2},{value:"<RootSearchSuggestField />",id:"rootsearchsuggestfield-",level:3},{value:"<Search />",id:"search-",level:3},{value:"<SearchSuggestField />",id:"searchsuggestfield-",level:3},{value:"<UserLogin />",id:"userlogin-",level:3},{value:"Context",id:"context",level:2}];function l(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"richie"})," is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages."]}),"\n",(0,s.jsx)(n.h2,{id:"rendering-components",children:"Rendering components"}),"\n",(0,s.jsx)(n.p,{children:"We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there."}),"\n",(0,s.jsxs)(n.p,{children:["We decided to use a specific CSS class name along with its modifiers. We reserve the ",(0,s.jsx)(n.code,{children:"richie-react"})," class and its modified children for this purpose."]}),"\n",(0,s.jsxs)(n.p,{children:["Additionally, components including internationalized data or strings need to know which locale to use. They will pick up the locale specified through the ",(0,s.jsx)(n.code,{children:"lang"})," attribute of the ",(0,s.jsx)(n.code,{children:""})," element, which is a requirement to have an accessible page anyway."]}),"\n",(0,s.jsx)(n.p,{children:"They use the BCP47/RFC5646 format."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-html",children:'\n'})}),"\n",(0,s.jsx)(n.h3,{id:"example",children:"Example"}),"\n",(0,s.jsxs)(n.p,{children:["Here is how we would call a ",(0,s.jsx)(n.code,{children:""})," component from a template, a plugin or a snippet:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-html",children:'\n'})}),"\n",(0,s.jsx)(n.p,{children:"When our JS is loaded, it will recognize this as an element it must take over, and render the FeaturedCourses component in this element."}),"\n",(0,s.jsx)(n.h2,{id:"passing-properties-to-components",children:"Passing properties to components"}),"\n",(0,s.jsx)(n.p,{children:'Some of Richie\'s React components, and some of those you might want to write, require arguments or "props" to be passed to them. We could work around that by adding API routes to fetch these props, but that would add complexity and reduce performance.'}),"\n",(0,s.jsx)(n.p,{children:"Instead, we decided to normalize a simpler way for components in Richie to accept input from the Django template that is adding them to the DOM."}),"\n",(0,s.jsxs)(n.p,{children:["We can add a ",(0,s.jsx)(n.code,{children:"data-props"})," attribute on the element with the ",(0,s.jsx)(n.code,{children:"richie-react"})," class and write a JSON object as the value for this attribute. Each key-value pair in this object will be passed as a ",(0,s.jsx)(n.code,{children:"propName={propValue}"})," to the React component."]}),"\n",(0,s.jsx)(n.h3,{id:"example-1",children:"Example"}),"\n",(0,s.jsxs)(n.p,{children:["Here is how we would pass a ",(0,s.jsx)(n.code,{children:'categories={[ "sociology", "anthropology" ]}'})," prop to our ",(0,s.jsx)(n.code,{children:""})," component:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-html",children:'\n'})}),"\n",(0,s.jsxs)(n.p,{children:["When the component is rendered, it will be passed a ",(0,s.jsx)(n.code,{children:"categories"})," prop with the relevant categories."]}),"\n",(0,s.jsx)(n.h2,{id:"built-in-components",children:"Built-in components"}),"\n",(0,s.jsx)(n.p,{children:"Here are the React component that Richie comes with and uses out of the box."}),"\n",(0,s.jsx)(n.h3,{id:"rootsearchsuggestfield-",children:""}),"\n",(0,s.jsxs)(n.p,{children:["Renders a course search bar, like the one that appears in the default ",(0,s.jsx)(n.code,{children:"Search"})," page."]}),"\n",(0,s.jsxs)(n.p,{children:["Interactions will send the user to the ",(0,s.jsx)(n.code,{children:"courseSearchPageUrl"})," url passed in the props, including the selected filter and/or search terms."]}),"\n",(0,s.jsx)(n.p,{children:"It also autocompletes user input with course names and allows users to go directly to the course page if they select a course name among the selected results."}),"\n",(0,s.jsx)(n.p,{children:"Props:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"courseSearchPageUrl"})," [required] \u2014 URL for the course search page users should be sent to when they select a suggestion that is not a course, or launch a search with text terms."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"context"})," [required] \u2014 see ",(0,s.jsx)(n.a,{href:"#context",children:"context"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"search-",children:""}),"\n",(0,s.jsxs)(n.p,{children:["Renders the full-page course search engine interface, including the search results, and filters pane, but not the suggest field (which can be added separately with ",(0,s.jsx)(n.code,{children:""}),") nor the page title."]}),"\n",(0,s.jsxs)(n.p,{children:["NB: the ",(0,s.jsx)(n.code,{children:"Search"})," Django template basically renders just this page. If you need this, use it instead. It is included here for completeness' sake."]}),"\n",(0,s.jsx)(n.p,{children:"Props:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"context"})," [required] \u2014 see ",(0,s.jsx)(n.a,{href:"#context",children:"context"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"searchsuggestfield-",children:""}),"\n",(0,s.jsxs)(n.p,{children:["Renders the course search bar that interacts directly with ",(0,s.jsx)(n.code,{children:""}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["It automatically communicates with ",(0,s.jsx)(n.code,{children:""})," through browser history APIs and a shared React provider. This one, unlike ",(0,s.jsx)(n.code,{children:""}),", is meant to be used in combination with ",(0,s.jsx)(n.code,{children:""})," (on the same page)."]}),"\n",(0,s.jsx)(n.p,{children:"Props:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"context"})," [required] \u2014 see ",(0,s.jsx)(n.a,{href:"#context",children:"context"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"userlogin-",children:""}),"\n",(0,s.jsxs)(n.p,{children:["Renders a component that uses the ",(0,s.jsx)(n.code,{children:"/users/whoami"})," endpoint to determine if the user is logged in and show them the appropriate interface: Signup/Login buttons or their name along with a Logout button."]}),"\n",(0,s.jsx)(n.p,{children:"Props:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"loginUrl"}),' [required] \u2014 the URL where the user is sent when they click on "Log in";']}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"logoutUrl"})," [required] \u2014 a link that logs the user out and redirects them (can be the standard django logout URL);"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"signupUrl"}),' [required] \u2014 the URL where the user is sent when they click on "Sign up".']}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"context",children:"Context"}),"\n",(0,s.jsxs)(n.p,{children:["All built-in components for Richie accept a ",(0,s.jsx)(n.code,{children:"context"})," prop, that may be required or optional, depending on the component."]}),"\n",(0,s.jsx)(n.p,{children:"It is used to pass app-wide contextual information pertaining to the current instance, deployment or theme of Richie."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-js",children:'{\n assets: {\n // SVG sprite used throughout Richie\n icons: "/path/to/icons/sprite.svg"\n }\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"Note that it might be expanded in further versions of Richie."})]})}function h(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},11151:(e,n,t)=>{t.d(n,{Z:()=>a,a:()=>r});var s=t(67294);const i={},o=s.createContext(i);function r(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/06447dd5.6cf6e11d.js b/assets/js/06447dd5.6cf6e11d.js new file mode 100644 index 0000000000..971dcb0ddb --- /dev/null +++ b/assets/js/06447dd5.6cf6e11d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[42814],{38178:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>c,toc:()=>d});var s=t(85893),i=t(11151);const o={id:"django-react-interop",title:"Connecting React components with Django",sidebar_label:"Django & React"},r=void 0,c={id:"django-react-interop",title:"Connecting React components with Django",description:"richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.",source:"@site/versioned_docs/version-2.23.0/django-react-interop.md",sourceDirName:".",slug:"/django-react-interop",permalink:"/docs/2.23.0/django-react-interop",draft:!1,unlisted:!1,tags:[],version:"2.23.0",lastUpdatedBy:"jbpenrath",lastUpdatedAt:1699548651e3,frontMatter:{id:"django-react-interop",title:"Connecting React components with Django",sidebar_label:"Django & React"},sidebar:"docs",previous:{title:"Search filters customization",permalink:"/docs/2.23.0/filters-customization"},next:{title:"Building the frontend",permalink:"/docs/2.23.0/building-the-frontend"}},a={},d=[{value:"Rendering components",id:"rendering-components",level:2},{value:"Example",id:"example",level:3},{value:"Passing properties to components",id:"passing-properties-to-components",level:2},{value:"Example",id:"example-1",level:3},{value:"Built-in components",id:"built-in-components",level:2},{value:"<RootSearchSuggestField />",id:"rootsearchsuggestfield-",level:3},{value:"<Search />",id:"search-",level:3},{value:"<SearchSuggestField />",id:"searchsuggestfield-",level:3},{value:"<UserLogin />",id:"userlogin-",level:3},{value:"Context",id:"context",level:2}];function l(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"richie"})," is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages."]}),"\n",(0,s.jsx)(n.h2,{id:"rendering-components",children:"Rendering components"}),"\n",(0,s.jsx)(n.p,{children:"We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there."}),"\n",(0,s.jsxs)(n.p,{children:["We decided to use a specific CSS class name along with its modifiers. We reserve the ",(0,s.jsx)(n.code,{children:"richie-react"})," class and its modified children for this purpose."]}),"\n",(0,s.jsxs)(n.p,{children:["Additionally, components including internationalized data or strings need to know which locale to use. They will pick up the locale specified through the ",(0,s.jsx)(n.code,{children:"lang"})," attribute of the ",(0,s.jsx)(n.code,{children:""})," element, which is a requirement to have an accessible page anyway."]}),"\n",(0,s.jsx)(n.p,{children:"They use the BCP47/RFC5646 format."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-html",children:'\n'})}),"\n",(0,s.jsx)(n.h3,{id:"example",children:"Example"}),"\n",(0,s.jsxs)(n.p,{children:["Here is how we would call a ",(0,s.jsx)(n.code,{children:""})," component from a template, a plugin or a snippet:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-html",children:'\n'})}),"\n",(0,s.jsx)(n.p,{children:"When our JS is loaded, it will recognize this as an element it must take over, and render the FeaturedCourses component in this element."}),"\n",(0,s.jsx)(n.h2,{id:"passing-properties-to-components",children:"Passing properties to components"}),"\n",(0,s.jsx)(n.p,{children:'Some of Richie\'s React components, and some of those you might want to write, require arguments or "props" to be passed to them. We could work around that by adding API routes to fetch these props, but that would add complexity and reduce performance.'}),"\n",(0,s.jsx)(n.p,{children:"Instead, we decided to normalize a simpler way for components in Richie to accept input from the Django template that is adding them to the DOM."}),"\n",(0,s.jsxs)(n.p,{children:["We can add a ",(0,s.jsx)(n.code,{children:"data-props"})," attribute on the element with the ",(0,s.jsx)(n.code,{children:"richie-react"})," class and write a JSON object as the value for this attribute. Each key-value pair in this object will be passed as a ",(0,s.jsx)(n.code,{children:"propName={propValue}"})," to the React component."]}),"\n",(0,s.jsx)(n.h3,{id:"example-1",children:"Example"}),"\n",(0,s.jsxs)(n.p,{children:["Here is how we would pass a ",(0,s.jsx)(n.code,{children:'categories={[ "sociology", "anthropology" ]}'})," prop to our ",(0,s.jsx)(n.code,{children:""})," component:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-html",children:'\n'})}),"\n",(0,s.jsxs)(n.p,{children:["When the component is rendered, it will be passed a ",(0,s.jsx)(n.code,{children:"categories"})," prop with the relevant categories."]}),"\n",(0,s.jsx)(n.h2,{id:"built-in-components",children:"Built-in components"}),"\n",(0,s.jsx)(n.p,{children:"Here are the React component that Richie comes with and uses out of the box."}),"\n",(0,s.jsx)(n.h3,{id:"rootsearchsuggestfield-",children:""}),"\n",(0,s.jsxs)(n.p,{children:["Renders a course search bar, like the one that appears in the default ",(0,s.jsx)(n.code,{children:"Search"})," page."]}),"\n",(0,s.jsxs)(n.p,{children:["Interactions will send the user to the ",(0,s.jsx)(n.code,{children:"courseSearchPageUrl"})," url passed in the props, including the selected filter and/or search terms."]}),"\n",(0,s.jsx)(n.p,{children:"It also autocompletes user input with course names and allows users to go directly to the course page if they select a course name among the selected results."}),"\n",(0,s.jsx)(n.p,{children:"Props:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"courseSearchPageUrl"})," [required] \u2014 URL for the course search page users should be sent to when they select a suggestion that is not a course, or launch a search with text terms."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"context"})," [required] \u2014 see ",(0,s.jsx)(n.a,{href:"#context",children:"context"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"search-",children:""}),"\n",(0,s.jsxs)(n.p,{children:["Renders the full-page course search engine interface, including the search results, and filters pane, but not the suggest field (which can be added separately with ",(0,s.jsx)(n.code,{children:""}),") nor the page title."]}),"\n",(0,s.jsxs)(n.p,{children:["NB: the ",(0,s.jsx)(n.code,{children:"Search"})," Django template basically renders just this page. If you need this, use it instead. It is included here for completeness' sake."]}),"\n",(0,s.jsx)(n.p,{children:"Props:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"context"})," [required] \u2014 see ",(0,s.jsx)(n.a,{href:"#context",children:"context"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"searchsuggestfield-",children:""}),"\n",(0,s.jsxs)(n.p,{children:["Renders the course search bar that interacts directly with ",(0,s.jsx)(n.code,{children:""}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["It automatically communicates with ",(0,s.jsx)(n.code,{children:""})," through browser history APIs and a shared React provider. This one, unlike ",(0,s.jsx)(n.code,{children:""}),", is meant to be used in combination with ",(0,s.jsx)(n.code,{children:""})," (on the same page)."]}),"\n",(0,s.jsx)(n.p,{children:"Props:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"context"})," [required] \u2014 see ",(0,s.jsx)(n.a,{href:"#context",children:"context"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"userlogin-",children:""}),"\n",(0,s.jsxs)(n.p,{children:["Renders a component that uses the ",(0,s.jsx)(n.code,{children:"/users/whoami"})," endpoint to determine if the user is logged in and show them the appropriate interface: Signup/Login buttons or their name along with a Logout button."]}),"\n",(0,s.jsx)(n.p,{children:"Props:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"loginUrl"}),' [required] \u2014 the URL where the user is sent when they click on "Log in";']}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"logoutUrl"})," [required] \u2014 a link that logs the user out and redirects them (can be the standard django logout URL);"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"signupUrl"}),' [required] \u2014 the URL where the user is sent when they click on "Sign up".']}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"context",children:"Context"}),"\n",(0,s.jsxs)(n.p,{children:["All built-in components for Richie accept a ",(0,s.jsx)(n.code,{children:"context"})," prop, that may be required or optional, depending on the component."]}),"\n",(0,s.jsx)(n.p,{children:"It is used to pass app-wide contextual information pertaining to the current instance, deployment or theme of Richie."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-js",children:'{\n assets: {\n // SVG sprite used throughout Richie\n icons: "/path/to/icons/sprite.svg"\n }\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"Note that it might be expanded in further versions of Richie."})]})}function h(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},11151:(e,n,t)=>{t.d(n,{Z:()=>c,a:()=>r});var s=t(67294);const i={},o=s.createContext(i);function r(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/06bcdf26.1d5f8354.js b/assets/js/06bcdf26.1d5f8354.js new file mode 100644 index 0000000000..369f89ccd8 --- /dev/null +++ b/assets/js/06bcdf26.1d5f8354.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[11431],{28935:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>r,metadata:()=>d,toc:()=>a});var i=t(85893),o=t(11151);const r={id:"contributing-guide",title:"Contributing guide",sidebar_label:"Contributing guide"},s=void 0,d={id:"contributing-guide",title:"Contributing guide",description:"This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.",source:"@site/versioned_docs/version-2.9.1/contributing.md",sourceDirName:".",slug:"/contributing-guide",permalink:"/docs/2.9.1/contributing-guide",draft:!1,unlisted:!1,tags:[],version:"2.9.1",lastUpdatedBy:"Mehdi Benadda",lastUpdatedAt:1655108611e3,frontMatter:{id:"contributing-guide",title:"Contributing guide",sidebar_label:"Contributing guide"},sidebar:"docs",previous:{title:"Web Analytics",permalink:"/docs/2.9.1/web-analytics"},next:{title:"Accessibility testing",permalink:"/docs/2.9.1/accessibility-testing"}},c={},a=[{value:"Checking your code",id:"checking-your-code",level:2},{value:"Running tests",id:"running-tests",level:2},{value:"Running migrations",id:"running-migrations",level:2},{value:"Handling new dependencies",id:"handling-new-dependencies",level:2},{value:"Going further",id:"going-further",level:2}];function l(e){const n={a:"a",code:"code",h2:"h2",p:"p",pre:"pre",strong:"strong",...(0,o.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.p,{children:"This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions."}),"\n",(0,i.jsxs)(n.p,{children:["We try to raise our code quality standards and expect contributors to follow the recommandations\nfrom our ",(0,i.jsx)(n.a,{href:"https://openfun.gitbooks.io/handbook/content",children:"handbook"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"checking-your-code",children:"Checking your code"}),"\n",(0,i.jsx)(n.p,{children:"We use strict flake8, pylint, isort and black linters to check the validity of our backend code:"}),"\n",(0,i.jsx)(n.p,{children:"$ make lint-back"}),"\n",(0,i.jsx)(n.p,{children:"We use strict eslint and prettier to check the validity of our frontend code:"}),"\n",(0,i.jsx)(n.p,{children:"$ make lint-front"}),"\n",(0,i.jsx)(n.h2,{id:"running-tests",children:"Running tests"}),"\n",(0,i.jsx)(n.p,{children:"On the backend, we use pytest to run our test suite:"}),"\n",(0,i.jsx)(n.p,{children:"$ make test-back"}),"\n",(0,i.jsx)(n.p,{children:"On the frontend, we use karma to run our test suite:"}),"\n",(0,i.jsx)(n.p,{children:"$ make test-front"}),"\n",(0,i.jsx)(n.h2,{id:"running-migrations",children:"Running migrations"}),"\n",(0,i.jsxs)(n.p,{children:["The first time you start the project with ",(0,i.jsx)(n.code,{children:"make bootstrap"}),", the ",(0,i.jsx)(n.code,{children:"db"})," container automatically\ncreates a fresh database named ",(0,i.jsx)(n.code,{children:"richie"})," and performs database migrations. Each time a new\n",(0,i.jsx)(n.strong,{children:"database migration"})," is added to the code, you can synchronize the database schema by running:"]}),"\n",(0,i.jsx)(n.p,{children:"$ make migrate"}),"\n",(0,i.jsx)(n.h2,{id:"handling-new-dependencies",children:"Handling new dependencies"}),"\n",(0,i.jsx)(n.p,{children:"Each time you add new front-end or back-end dependencies, you will need to rebuild the\napplication. We recommend to use:"}),"\n",(0,i.jsx)(n.p,{children:"$ make bootstrap"}),"\n",(0,i.jsx)(n.h2,{id:"going-further",children:"Going further"}),"\n",(0,i.jsx)(n.p,{children:"To see all available commands, run:"}),"\n",(0,i.jsx)(n.p,{children:"$ make"}),"\n",(0,i.jsxs)(n.p,{children:["We also provide shortcuts for docker-compose commands as sugar scripts in the\n",(0,i.jsx)(n.code,{children:"bin/"})," directory:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"bin\n\u251c\u2500\u2500 exec\n\u251c\u2500\u2500 pylint\n\u251c\u2500\u2500 pytest\n\u2514\u2500\u2500 run\n"})}),"\n",(0,i.jsxs)(n.p,{children:["More details and tips & tricks can be found in our ",(0,i.jsx)(n.a,{href:"docker-development.md",children:"development with Docker\ndocumentation"})]})]})}function u(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},11151:(e,n,t)=>{t.d(n,{Z:()=>d,a:()=>s});var i=t(67294);const o={},r=i.createContext(o);function s(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/06bcdf26.d190b60e.js b/assets/js/06bcdf26.d190b60e.js deleted file mode 100644 index 78eb11184b..0000000000 --- a/assets/js/06bcdf26.d190b60e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[11431],{28935:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>r,metadata:()=>d,toc:()=>a});var i=t(85893),o=t(11151);const r={id:"contributing-guide",title:"Contributing guide",sidebar_label:"Contributing guide"},s=void 0,d={id:"contributing-guide",title:"Contributing guide",description:"This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.",source:"@site/versioned_docs/version-2.9.1/contributing.md",sourceDirName:".",slug:"/contributing-guide",permalink:"/docs/2.9.1/contributing-guide",draft:!1,unlisted:!1,tags:[],version:"2.9.1",lastUpdatedBy:"Mehdi Benadda",lastUpdatedAt:1655108611,formattedLastUpdatedAt:"Jun 13, 2022",frontMatter:{id:"contributing-guide",title:"Contributing guide",sidebar_label:"Contributing guide"},sidebar:"docs",previous:{title:"Web Analytics",permalink:"/docs/2.9.1/web-analytics"},next:{title:"Accessibility testing",permalink:"/docs/2.9.1/accessibility-testing"}},c={},a=[{value:"Checking your code",id:"checking-your-code",level:2},{value:"Running tests",id:"running-tests",level:2},{value:"Running migrations",id:"running-migrations",level:2},{value:"Handling new dependencies",id:"handling-new-dependencies",level:2},{value:"Going further",id:"going-further",level:2}];function l(e){const n={a:"a",code:"code",h2:"h2",p:"p",pre:"pre",strong:"strong",...(0,o.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.p,{children:"This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions."}),"\n",(0,i.jsxs)(n.p,{children:["We try to raise our code quality standards and expect contributors to follow the recommandations\nfrom our ",(0,i.jsx)(n.a,{href:"https://openfun.gitbooks.io/handbook/content",children:"handbook"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"checking-your-code",children:"Checking your code"}),"\n",(0,i.jsx)(n.p,{children:"We use strict flake8, pylint, isort and black linters to check the validity of our backend code:"}),"\n",(0,i.jsx)(n.p,{children:"$ make lint-back"}),"\n",(0,i.jsx)(n.p,{children:"We use strict eslint and prettier to check the validity of our frontend code:"}),"\n",(0,i.jsx)(n.p,{children:"$ make lint-front"}),"\n",(0,i.jsx)(n.h2,{id:"running-tests",children:"Running tests"}),"\n",(0,i.jsx)(n.p,{children:"On the backend, we use pytest to run our test suite:"}),"\n",(0,i.jsx)(n.p,{children:"$ make test-back"}),"\n",(0,i.jsx)(n.p,{children:"On the frontend, we use karma to run our test suite:"}),"\n",(0,i.jsx)(n.p,{children:"$ make test-front"}),"\n",(0,i.jsx)(n.h2,{id:"running-migrations",children:"Running migrations"}),"\n",(0,i.jsxs)(n.p,{children:["The first time you start the project with ",(0,i.jsx)(n.code,{children:"make bootstrap"}),", the ",(0,i.jsx)(n.code,{children:"db"})," container automatically\ncreates a fresh database named ",(0,i.jsx)(n.code,{children:"richie"})," and performs database migrations. Each time a new\n",(0,i.jsx)(n.strong,{children:"database migration"})," is added to the code, you can synchronize the database schema by running:"]}),"\n",(0,i.jsx)(n.p,{children:"$ make migrate"}),"\n",(0,i.jsx)(n.h2,{id:"handling-new-dependencies",children:"Handling new dependencies"}),"\n",(0,i.jsx)(n.p,{children:"Each time you add new front-end or back-end dependencies, you will need to rebuild the\napplication. We recommend to use:"}),"\n",(0,i.jsx)(n.p,{children:"$ make bootstrap"}),"\n",(0,i.jsx)(n.h2,{id:"going-further",children:"Going further"}),"\n",(0,i.jsx)(n.p,{children:"To see all available commands, run:"}),"\n",(0,i.jsx)(n.p,{children:"$ make"}),"\n",(0,i.jsxs)(n.p,{children:["We also provide shortcuts for docker-compose commands as sugar scripts in the\n",(0,i.jsx)(n.code,{children:"bin/"})," directory:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"bin\n\u251c\u2500\u2500 exec\n\u251c\u2500\u2500 pylint\n\u251c\u2500\u2500 pytest\n\u2514\u2500\u2500 run\n"})}),"\n",(0,i.jsxs)(n.p,{children:["More details and tips & tricks can be found in our ",(0,i.jsx)(n.a,{href:"docker-development.md",children:"development with Docker\ndocumentation"})]})]})}function u(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},11151:(e,n,t)=>{t.d(n,{Z:()=>d,a:()=>s});var i=t(67294);const o={},r=i.createContext(o);function s(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/06e6648e.0cbd1b43.js b/assets/js/06e6648e.0cbd1b43.js deleted file mode 100644 index 9b4e733062..0000000000 --- a/assets/js/06e6648e.0cbd1b43.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[60384],{10010:(n,e,t)=>{t.r(e),t.d(e,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>s,toc:()=>c});var i=t(85893),o=t(11151);const a={id:"internationalization",title:"Internationalization",sidebar_label:"I18n"},r=void 0,s={id:"internationalization",title:"Internationalization",description:"richie has built-in localization and internationalization:",source:"@site/versioned_docs/version-2.14.0/internationalization.md",sourceDirName:".",slug:"/internationalization",permalink:"/docs/2.14.0/internationalization",draft:!1,unlisted:!1,tags:[],version:"2.14.0",lastUpdatedBy:"Mehdi Benadda",lastUpdatedAt:1655108611,formattedLastUpdatedAt:"Jun 13, 2022",frontMatter:{id:"internationalization",title:"Internationalization",sidebar_label:"I18n"},sidebar:"docs",previous:{title:"Building the frontend",permalink:"/docs/2.14.0/building-the-frontend"},next:{title:"Frontend overrides",permalink:"/docs/2.14.0/frontend-overrides"}},d={},c=[{value:"Contributing as a translator or proof-reader",id:"contributing-as-a-translator-or-proof-reader",level:2},{value:"Sign-up on Crowdin",id:"sign-up-on-crowdin",level:3},{value:"Join the Richie project",id:"join-the-richie-project",level:3},{value:"Add a new language",id:"add-a-new-language",level:3}];function l(n){const e={a:"a",code:"code",h2:"h2",h3:"h3",img:"img",li:"li",p:"p",ul:"ul",...(0,o.a)(),...n.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(e.p,{children:[(0,i.jsx)(e.code,{children:"richie"})," has built-in localization and internationalization:"]}),"\n",(0,i.jsxs)(e.ul,{children:["\n",(0,i.jsx)(e.li,{children:"On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,"}),"\n",(0,i.jsx)(e.li,{children:"On the frontend, we use React Intl."}),"\n"]}),"\n",(0,i.jsx)(e.h2,{id:"contributing-as-a-translator-or-proof-reader",children:"Contributing as a translator or proof-reader"}),"\n",(0,i.jsxs)(e.p,{children:["We use the ",(0,i.jsx)(e.a,{href:"https://crowdin.com",children:"Crowdin"})," web platform to translate Richie to different languages.\nAll translations are hosted at ",(0,i.jsx)(e.a,{href:"https://i18n.richie.education",children:"https://i18n.richie.education"}),", which allows translators and\nproof-readers to contribute on translations in the languages they master."]}),"\n",(0,i.jsx)(e.h3,{id:"sign-up-on-crowdin",children:"Sign-up on Crowdin"}),"\n",(0,i.jsxs)(e.p,{children:["If you don't have an account on Crowdin already, go to ",(0,i.jsx)(e.a,{href:"https://accounts.crowdin.com/register",children:"https://accounts.crowdin.com/register"})," and\nfill out the form to create a free account."]}),"\n",(0,i.jsx)(e.h3,{id:"join-the-richie-project",children:"Join the Richie project"}),"\n",(0,i.jsxs)(e.p,{children:["Now that you have an account on Crowdin,\n",(0,i.jsx)(e.a,{href:"https://crowdin.com/project/richie",children:'look for the project called "Richie"'}),', select the language\non which you wish to contribute and click the "Join" button as demonstrated below:']}),"\n",(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{alt:"How to join Richie on Crowdin",src:t(17177).Z+"",width:"2462",height:"1506"})}),"\n",(0,i.jsx)(e.p,{children:"We will then review you application and you should soon start translating strings!"}),"\n",(0,i.jsxs)(e.p,{children:["For more information on how Crowdin works, you can refer to\n",(0,i.jsx)(e.a,{href:"https://support.crowdin.com",children:"their documentation"}),"."]}),"\n",(0,i.jsx)(e.h3,{id:"add-a-new-language",children:"Add a new language"}),"\n",(0,i.jsxs)(e.p,{children:['If Richie is not yet translated in the language you want, let us know by clicking the "contact"\nlink on ',(0,i.jsx)(e.a,{href:"https://i18n.richie.education",children:"Richie's Crowdin profile page"})," and we will consider adding\nit."]}),"\n",(0,i.jsx)(e.p,{children:"If you request a new language, the Richie community will expect you to keep this language\nup-to-date each time strings are modified or new strings are added, and this before each\nrelease."}),"\n",(0,i.jsx)(e.p,{children:"Before asking for a new language, make sure it does not already exist. If your language already\nexists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider\ncontributing on the existing language if your resources to contribute are limited."})]})}function h(n={}){const{wrapper:e}={...(0,o.a)(),...n.components};return e?(0,i.jsx)(e,{...n,children:(0,i.jsx)(l,{...n})}):l(n)}},17177:(n,e,t)=>{t.d(e,{Z:()=>i});const i=t.p+"assets/images/crowdin-join-richie-fd505b1a132bafb2bdafc715649a7c0f.gif"},11151:(n,e,t)=>{t.d(e,{Z:()=>s,a:()=>r});var i=t(67294);const o={},a=i.createContext(o);function r(n){const e=i.useContext(a);return i.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function s(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(o):n.components||o:r(n.components),i.createElement(a.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/06e6648e.52069984.js b/assets/js/06e6648e.52069984.js new file mode 100644 index 0000000000..ad3c9ee4cf --- /dev/null +++ b/assets/js/06e6648e.52069984.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[60384],{10010:(n,e,i)=>{i.r(e),i.d(e,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>s,toc:()=>d});var t=i(85893),o=i(11151);const a={id:"internationalization",title:"Internationalization",sidebar_label:"I18n"},r=void 0,s={id:"internationalization",title:"Internationalization",description:"richie has built-in localization and internationalization:",source:"@site/versioned_docs/version-2.14.0/internationalization.md",sourceDirName:".",slug:"/internationalization",permalink:"/docs/2.14.0/internationalization",draft:!1,unlisted:!1,tags:[],version:"2.14.0",lastUpdatedBy:"Mehdi Benadda",lastUpdatedAt:1655108611e3,frontMatter:{id:"internationalization",title:"Internationalization",sidebar_label:"I18n"},sidebar:"docs",previous:{title:"Building the frontend",permalink:"/docs/2.14.0/building-the-frontend"},next:{title:"Frontend overrides",permalink:"/docs/2.14.0/frontend-overrides"}},c={},d=[{value:"Contributing as a translator or proof-reader",id:"contributing-as-a-translator-or-proof-reader",level:2},{value:"Sign-up on Crowdin",id:"sign-up-on-crowdin",level:3},{value:"Join the Richie project",id:"join-the-richie-project",level:3},{value:"Add a new language",id:"add-a-new-language",level:3}];function l(n){const e={a:"a",code:"code",h2:"h2",h3:"h3",img:"img",li:"li",p:"p",ul:"ul",...(0,o.a)(),...n.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:"richie"})," has built-in localization and internationalization:"]}),"\n",(0,t.jsxs)(e.ul,{children:["\n",(0,t.jsx)(e.li,{children:"On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,"}),"\n",(0,t.jsx)(e.li,{children:"On the frontend, we use React Intl."}),"\n"]}),"\n",(0,t.jsx)(e.h2,{id:"contributing-as-a-translator-or-proof-reader",children:"Contributing as a translator or proof-reader"}),"\n",(0,t.jsxs)(e.p,{children:["We use the ",(0,t.jsx)(e.a,{href:"https://crowdin.com",children:"Crowdin"})," web platform to translate Richie to different languages.\nAll translations are hosted at ",(0,t.jsx)(e.a,{href:"https://i18n.richie.education",children:"https://i18n.richie.education"}),", which allows translators and\nproof-readers to contribute on translations in the languages they master."]}),"\n",(0,t.jsx)(e.h3,{id:"sign-up-on-crowdin",children:"Sign-up on Crowdin"}),"\n",(0,t.jsxs)(e.p,{children:["If you don't have an account on Crowdin already, go to ",(0,t.jsx)(e.a,{href:"https://accounts.crowdin.com/register",children:"https://accounts.crowdin.com/register"})," and\nfill out the form to create a free account."]}),"\n",(0,t.jsx)(e.h3,{id:"join-the-richie-project",children:"Join the Richie project"}),"\n",(0,t.jsxs)(e.p,{children:["Now that you have an account on Crowdin,\n",(0,t.jsx)(e.a,{href:"https://crowdin.com/project/richie",children:'look for the project called "Richie"'}),', select the language\non which you wish to contribute and click the "Join" button as demonstrated below:']}),"\n",(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{alt:"How to join Richie on Crowdin",src:i(17177).Z+"",width:"2462",height:"1506"})}),"\n",(0,t.jsx)(e.p,{children:"We will then review you application and you should soon start translating strings!"}),"\n",(0,t.jsxs)(e.p,{children:["For more information on how Crowdin works, you can refer to\n",(0,t.jsx)(e.a,{href:"https://support.crowdin.com",children:"their documentation"}),"."]}),"\n",(0,t.jsx)(e.h3,{id:"add-a-new-language",children:"Add a new language"}),"\n",(0,t.jsxs)(e.p,{children:['If Richie is not yet translated in the language you want, let us know by clicking the "contact"\nlink on ',(0,t.jsx)(e.a,{href:"https://i18n.richie.education",children:"Richie's Crowdin profile page"})," and we will consider adding\nit."]}),"\n",(0,t.jsx)(e.p,{children:"If you request a new language, the Richie community will expect you to keep this language\nup-to-date each time strings are modified or new strings are added, and this before each\nrelease."}),"\n",(0,t.jsx)(e.p,{children:"Before asking for a new language, make sure it does not already exist. If your language already\nexists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider\ncontributing on the existing language if your resources to contribute are limited."})]})}function h(n={}){const{wrapper:e}={...(0,o.a)(),...n.components};return e?(0,t.jsx)(e,{...n,children:(0,t.jsx)(l,{...n})}):l(n)}},17177:(n,e,i)=>{i.d(e,{Z:()=>t});const t=i.p+"assets/images/crowdin-join-richie-fd505b1a132bafb2bdafc715649a7c0f.gif"},11151:(n,e,i)=>{i.d(e,{Z:()=>s,a:()=>r});var t=i(67294);const o={},a=t.createContext(o);function r(n){const e=t.useContext(a);return t.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function s(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(o):n.components||o:r(n.components),t.createElement(a.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/07ba485a.5951a251.js b/assets/js/07ba485a.5951a251.js deleted file mode 100644 index c9ae2fc25b..0000000000 --- a/assets/js/07ba485a.5951a251.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[83484],{71118:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>o,toc:()=>c});var i=t(85893),s=t(11151);const r={id:"filters-customization",title:"Customizing search filters",sidebar_label:"Search filters customization"},a=void 0,o={id:"filters-customization",title:"Customizing search filters",description:"You may want to customize the filters on the left side bar of the search page.",source:"@site/versioned_docs/version-2.20.1/filters-customization.md",sourceDirName:".",slug:"/filters-customization",permalink:"/docs/2.20.1/filters-customization",draft:!1,unlisted:!1,tags:[],version:"2.20.1",lastUpdatedBy:"jbpenrath",lastUpdatedAt:1677062183,formattedLastUpdatedAt:"Feb 22, 2023",frontMatter:{id:"filters-customization",title:"Customizing search filters",sidebar_label:"Search filters customization"},sidebar:"docs",previous:{title:"Start your own site",permalink:"/docs/2.20.1/cookiecutter"},next:{title:"Django & React",permalink:"/docs/2.20.1/django-react-interop"}},l={},c=[{value:"Filters configuration",id:"filters-configuration",level:2},{value:"Filters presentation",id:"filters-presentation",level:2},{value:"Writing your own custom filters",id:"writing-your-own-custom-filters",level:2}];function h(e){const n={a:"a",code:"code",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.p,{children:"You may want to customize the filters on the left side bar of the search page."}),"\n",(0,i.jsx)(n.p,{children:"Richie makes it easy to choose which filters you want to display among the existing filters\nand in which order. You can also configure the existing filters to change their title or the\nway they behave. Lastly, you can completely override a filter or create your own custom filter\nfrom scratch."}),"\n",(0,i.jsx)(n.h2,{id:"filters-configuration",children:"Filters configuration"}),"\n",(0,i.jsxs)(n.p,{children:["Filters must first be defined in the ",(0,i.jsx)(n.code,{children:"FILTERS_CONFIGURATION"})," setting. It is a dictionary defining\nfor each filter, a predefined ",(0,i.jsx)(n.code,{children:"class"})," in the code where the filter is implemented and the\nparameters to apply to this class when instantiating it."]}),"\n",(0,i.jsx)(n.p,{children:"Let's study a few examples of filters in the default configuration:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:'FILTERS_CONFIGURATION = {\n ...\n "pace": {\n "class": "richie.apps.search.filter_definitions.StaticChoicesFilterDefinition",\n "params": {\n "fragment_map": {\n "self-paced": [{"bool": {"must_not": {"exists": {"field": "pace"}}}}],\n "lt-1h": [{"range": {"pace": {"lt": 60}}}],\n "1h-2h": [{"range": {"pace": {"gte": 60, "lte": 120}}}],\n "gt-2h": [{"range": {"pace": {"gt": 120}}}],\n },\n "human_name": _("Weekly pace"),\n "min_doc_count": 0,\n "sorting": "conf",\n "values": {\n "self-paced": _("Self-paced"),\n "lt-1h": _("Less than one hour"),\n "1h-2h": _("One to two hours"),\n "gt-2h": _("More than two hours"),\n },\n },\n },\n ...\n}\n'})}),"\n",(0,i.jsxs)(n.p,{children:["This filter uses the ",(0,i.jsx)(n.code,{children:"StaticChoicesFilterDefinition"})," filter definition class and allows filtering\non the ",(0,i.jsx)(n.code,{children:"pace"})," field present in the Elasticsearch index. The ",(0,i.jsx)(n.code,{children:"values"})," parameter defines 4 ranges\nand their human readable format that will appear as 4 filtering options to the user."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"fragment_map"})," parameter defines a fragment of the Elasticsearch query to apply on the ",(0,i.jsx)(n.code,{children:"pace"}),"\nfield when one of these options is selected."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"human_name"}),"parameter defines how the filter is entitled. It is defined as a lazy i18n string\nso that it can be translated."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"sorting"})," parameter determines how the facets are sorted in the left side panel of the filter:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"conf"}),": facets are sorted as defined in the ",(0,i.jsx)(n.code,{children:"values"})," configuration parameter"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"count"}),": facets are sorted according to the number of course results associated with each facet"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"name"}),": facets are sorted by their name in alphabetical order"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"min_doc_count"})," parameter defines how many associated results a facet must have at the minimum\nbefore it is displayed as an option for the filter."]}),"\n",(0,i.jsx)(n.p,{children:"Let's study another interesting example:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:'FILTERS_CONFIGURATION = {\n ...\n "organizations": {\n "class": "richie.apps.search.filter_definitions.IndexableHierarchicalFilterDefinition",\n "params": {\n "human_name": _("Organizations"),\n "is_autocompletable": True,\n "is_drilldown": False,\n "is_searchable": True,\n "min_doc_count": 0,\n "reverse_id": "organizations",\n },\n },\n ...\n}\n'})}),"\n",(0,i.jsxs)(n.p,{children:["This filter uses the ",(0,i.jsx)(n.code,{children:"IndexableHierarchicalFilterDefinition"})," filter definition class and allows\nfiltering on the link between course pages and other pages identified by their IDs like for\nexample here ",(0,i.jsx)(n.code,{children:"Organization"})," pages."]}),"\n",(0,i.jsxs)(n.p,{children:["In the example above, when an option is selected, results will only include the courses for which\nthe ",(0,i.jsx)(n.code,{children:"organizations"})," field in the index is including the ID of the selected organization page."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"reverse_id"})," parameter should point to a page's reverse ID (see DjangoCMS documentation) in\nthe CMS. The filter will propose a filtering option for each children organization under this\npage."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"is_autocompletable"})," field determines whether organizations should be searched and suggested\nby the autocomplete feature (organizations must have an associated index and API endpoint for\nautocompletion carrying the same name)."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"is_drilldown"})," parameter determines whether the filter is limited to one active value at a\ntime or allows multi-facetting."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"is_searchable"}),' field determines whether organizations filters should present a "more options"\nbutton in case there are more facet options in results than can be displayed (organizations must\nhave an associated API endpoint for full-text search, carrying the same name).']}),"\n",(0,i.jsx)(n.p,{children:"Lastly, let's look at nested filters which, as their name indicates, allow filtering on nested\nfields."}),"\n",(0,i.jsxs)(n.p,{children:["For example, in the course index, one of the fields is named ",(0,i.jsx)(n.code,{children:"course_runs"})," and contains a list of\nobjects in the following format:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:'"course_runs": [\n {\n "start": "2022-09-09T09:00:00.000000",\n "end": "2021-10-30T00:00:00.000000Z",\n "enrollment_start": "2022-08-01T09:00:00.000000Z",\n "enrollment_end": "2022-09-08T00:00:00.000000Z",\n "languages": ["en", "fr"],\n },\n {\n "start": "2023-03-01T09:00:00.000000",\n "end": "2023-06-03T00:00:00.000000Z",\n "enrollment_start": "2023-01-01T09:00:00.000000Z",\n "enrollment_end": "2023-03-01T00:00:00.000000Z",\n "languages": ["fr"],\n },\n]\n'})}),"\n",(0,i.jsx)(n.p,{children:"If we want to filter courses that are available in the english language, we can thus configure the\nfollowing filter:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:'FILTERS_CONFIGURATION = {\n ...\n "course_runs": {\n "class": "richie.apps.search.filter_definitions.NestingWrapper",\n "params": {\n "filters": {\n "languages": {\n "class": "richie.apps.search.filter_definitions.LanguagesFilterDefinition",\n "params": {\n "human_name": _("Languages"),\n # There are too many available languages to show them all, all the time.\n # Eg. 200 languages, 190+ of which will have 0 matching courses.\n "min_doc_count": 1,\n },\n },\n }\n },\n },\n ...\n}\n'})}),"\n",(0,i.jsx)(n.h2,{id:"filters-presentation",children:"Filters presentation"}),"\n",(0,i.jsxs)(n.p,{children:["Which filters are displayed in the left side bar of the search page and in which order is defined\nby the ",(0,i.jsx)(n.code,{children:"RICHIE_FILTERS_PRESENTATION"})," setting."]}),"\n",(0,i.jsxs)(n.p,{children:["This setting is expecting a list of strings, which are the names of the filters as defined\nin the ",(0,i.jsx)(n.code,{children:"FILTERS_CONFIGURATION"})," setting decribed in the previous section. If it, for example,\ncontains the 3 filters presented in the previous section, we could define the following\npresentation:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:'RICHIE_FILTERS_PRESENTATION = ["organizations", "languages", "pace"]\n'})}),"\n",(0,i.jsx)(n.h2,{id:"writing-your-own-custom-filters",children:"Writing your own custom filters"}),"\n",(0,i.jsxs)(n.p,{children:["You can write your own filters from scratch although we must warn you that it is not trivial\nbecause it requires a good knowledge of Elasticsearch and studying the mapping defined in the\n",(0,i.jsx)(n.a,{href:"https://github.com/openfun/richie/blob/master/src/richie/apps/search/indexers/courses.py",children:"courses indexer"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["A filter is a class deriving from ",(0,i.jsx)(n.a,{href:"https://github.com/openfun/richie/blob/master/src/richie/apps/search/filter_definitions/base.py",children:"BaseFilterDefinition"})," and defining methods to return the\ninformation to display the filter and query fragments for elasticsearch:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"get_form_fields"}),": returns the form field instance that will be used to parse and validate this\nfilter's values from the querystring"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"get_query_fragment"}),": returns the query fragment to use as filter in ElasticSearch"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"get_aggs_fragment"}),": returns the query fragment to use to extract facets from\nElasticSearch aggregations"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"get_facet_info"}),": returns the dynamic facet information from a filter's Elasticsearch facet\nresults. Together with the facet's static information, it will be used to display the filter\nin its current status in the left side panel of the search page."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["We will not go into more details here about how filter definition classes work, but you can refer\nto the code of the existing filters as good examples of what is possible. The code, although not\ntrivial, was given much care and includes many comments in an attempt to help writing new custom\nfilters. Of course, don't hesitate to ask for help by\n",(0,i.jsx)(n.a,{href:"https://github.com/openfun/richie/issues",children:"opening an issue"}),"!"]})]})}function d(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(h,{...e})}):h(e)}},11151:(e,n,t)=>{t.d(n,{Z:()=>o,a:()=>a});var i=t(67294);const s={},r=i.createContext(s);function a(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/07ba485a.ff70a59c.js b/assets/js/07ba485a.ff70a59c.js new file mode 100644 index 0000000000..36f0e5dd2f --- /dev/null +++ b/assets/js/07ba485a.ff70a59c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[83484],{71118:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>o,toc:()=>c});var i=t(85893),s=t(11151);const r={id:"filters-customization",title:"Customizing search filters",sidebar_label:"Search filters customization"},a=void 0,o={id:"filters-customization",title:"Customizing search filters",description:"You may want to customize the filters on the left side bar of the search page.",source:"@site/versioned_docs/version-2.20.1/filters-customization.md",sourceDirName:".",slug:"/filters-customization",permalink:"/docs/2.20.1/filters-customization",draft:!1,unlisted:!1,tags:[],version:"2.20.1",lastUpdatedBy:"jbpenrath",lastUpdatedAt:1677062183e3,frontMatter:{id:"filters-customization",title:"Customizing search filters",sidebar_label:"Search filters customization"},sidebar:"docs",previous:{title:"Start your own site",permalink:"/docs/2.20.1/cookiecutter"},next:{title:"Django & React",permalink:"/docs/2.20.1/django-react-interop"}},l={},c=[{value:"Filters configuration",id:"filters-configuration",level:2},{value:"Filters presentation",id:"filters-presentation",level:2},{value:"Writing your own custom filters",id:"writing-your-own-custom-filters",level:2}];function h(e){const n={a:"a",code:"code",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.p,{children:"You may want to customize the filters on the left side bar of the search page."}),"\n",(0,i.jsx)(n.p,{children:"Richie makes it easy to choose which filters you want to display among the existing filters\nand in which order. You can also configure the existing filters to change their title or the\nway they behave. Lastly, you can completely override a filter or create your own custom filter\nfrom scratch."}),"\n",(0,i.jsx)(n.h2,{id:"filters-configuration",children:"Filters configuration"}),"\n",(0,i.jsxs)(n.p,{children:["Filters must first be defined in the ",(0,i.jsx)(n.code,{children:"FILTERS_CONFIGURATION"})," setting. It is a dictionary defining\nfor each filter, a predefined ",(0,i.jsx)(n.code,{children:"class"})," in the code where the filter is implemented and the\nparameters to apply to this class when instantiating it."]}),"\n",(0,i.jsx)(n.p,{children:"Let's study a few examples of filters in the default configuration:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:'FILTERS_CONFIGURATION = {\n ...\n "pace": {\n "class": "richie.apps.search.filter_definitions.StaticChoicesFilterDefinition",\n "params": {\n "fragment_map": {\n "self-paced": [{"bool": {"must_not": {"exists": {"field": "pace"}}}}],\n "lt-1h": [{"range": {"pace": {"lt": 60}}}],\n "1h-2h": [{"range": {"pace": {"gte": 60, "lte": 120}}}],\n "gt-2h": [{"range": {"pace": {"gt": 120}}}],\n },\n "human_name": _("Weekly pace"),\n "min_doc_count": 0,\n "sorting": "conf",\n "values": {\n "self-paced": _("Self-paced"),\n "lt-1h": _("Less than one hour"),\n "1h-2h": _("One to two hours"),\n "gt-2h": _("More than two hours"),\n },\n },\n },\n ...\n}\n'})}),"\n",(0,i.jsxs)(n.p,{children:["This filter uses the ",(0,i.jsx)(n.code,{children:"StaticChoicesFilterDefinition"})," filter definition class and allows filtering\non the ",(0,i.jsx)(n.code,{children:"pace"})," field present in the Elasticsearch index. The ",(0,i.jsx)(n.code,{children:"values"})," parameter defines 4 ranges\nand their human readable format that will appear as 4 filtering options to the user."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"fragment_map"})," parameter defines a fragment of the Elasticsearch query to apply on the ",(0,i.jsx)(n.code,{children:"pace"}),"\nfield when one of these options is selected."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"human_name"}),"parameter defines how the filter is entitled. It is defined as a lazy i18n string\nso that it can be translated."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"sorting"})," parameter determines how the facets are sorted in the left side panel of the filter:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"conf"}),": facets are sorted as defined in the ",(0,i.jsx)(n.code,{children:"values"})," configuration parameter"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"count"}),": facets are sorted according to the number of course results associated with each facet"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"name"}),": facets are sorted by their name in alphabetical order"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"min_doc_count"})," parameter defines how many associated results a facet must have at the minimum\nbefore it is displayed as an option for the filter."]}),"\n",(0,i.jsx)(n.p,{children:"Let's study another interesting example:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:'FILTERS_CONFIGURATION = {\n ...\n "organizations": {\n "class": "richie.apps.search.filter_definitions.IndexableHierarchicalFilterDefinition",\n "params": {\n "human_name": _("Organizations"),\n "is_autocompletable": True,\n "is_drilldown": False,\n "is_searchable": True,\n "min_doc_count": 0,\n "reverse_id": "organizations",\n },\n },\n ...\n}\n'})}),"\n",(0,i.jsxs)(n.p,{children:["This filter uses the ",(0,i.jsx)(n.code,{children:"IndexableHierarchicalFilterDefinition"})," filter definition class and allows\nfiltering on the link between course pages and other pages identified by their IDs like for\nexample here ",(0,i.jsx)(n.code,{children:"Organization"})," pages."]}),"\n",(0,i.jsxs)(n.p,{children:["In the example above, when an option is selected, results will only include the courses for which\nthe ",(0,i.jsx)(n.code,{children:"organizations"})," field in the index is including the ID of the selected organization page."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"reverse_id"})," parameter should point to a page's reverse ID (see DjangoCMS documentation) in\nthe CMS. The filter will propose a filtering option for each children organization under this\npage."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"is_autocompletable"})," field determines whether organizations should be searched and suggested\nby the autocomplete feature (organizations must have an associated index and API endpoint for\nautocompletion carrying the same name)."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"is_drilldown"})," parameter determines whether the filter is limited to one active value at a\ntime or allows multi-facetting."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"is_searchable"}),' field determines whether organizations filters should present a "more options"\nbutton in case there are more facet options in results than can be displayed (organizations must\nhave an associated API endpoint for full-text search, carrying the same name).']}),"\n",(0,i.jsx)(n.p,{children:"Lastly, let's look at nested filters which, as their name indicates, allow filtering on nested\nfields."}),"\n",(0,i.jsxs)(n.p,{children:["For example, in the course index, one of the fields is named ",(0,i.jsx)(n.code,{children:"course_runs"})," and contains a list of\nobjects in the following format:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:'"course_runs": [\n {\n "start": "2022-09-09T09:00:00.000000",\n "end": "2021-10-30T00:00:00.000000Z",\n "enrollment_start": "2022-08-01T09:00:00.000000Z",\n "enrollment_end": "2022-09-08T00:00:00.000000Z",\n "languages": ["en", "fr"],\n },\n {\n "start": "2023-03-01T09:00:00.000000",\n "end": "2023-06-03T00:00:00.000000Z",\n "enrollment_start": "2023-01-01T09:00:00.000000Z",\n "enrollment_end": "2023-03-01T00:00:00.000000Z",\n "languages": ["fr"],\n },\n]\n'})}),"\n",(0,i.jsx)(n.p,{children:"If we want to filter courses that are available in the english language, we can thus configure the\nfollowing filter:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:'FILTERS_CONFIGURATION = {\n ...\n "course_runs": {\n "class": "richie.apps.search.filter_definitions.NestingWrapper",\n "params": {\n "filters": {\n "languages": {\n "class": "richie.apps.search.filter_definitions.LanguagesFilterDefinition",\n "params": {\n "human_name": _("Languages"),\n # There are too many available languages to show them all, all the time.\n # Eg. 200 languages, 190+ of which will have 0 matching courses.\n "min_doc_count": 1,\n },\n },\n }\n },\n },\n ...\n}\n'})}),"\n",(0,i.jsx)(n.h2,{id:"filters-presentation",children:"Filters presentation"}),"\n",(0,i.jsxs)(n.p,{children:["Which filters are displayed in the left side bar of the search page and in which order is defined\nby the ",(0,i.jsx)(n.code,{children:"RICHIE_FILTERS_PRESENTATION"})," setting."]}),"\n",(0,i.jsxs)(n.p,{children:["This setting is expecting a list of strings, which are the names of the filters as defined\nin the ",(0,i.jsx)(n.code,{children:"FILTERS_CONFIGURATION"})," setting decribed in the previous section. If it, for example,\ncontains the 3 filters presented in the previous section, we could define the following\npresentation:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:'RICHIE_FILTERS_PRESENTATION = ["organizations", "languages", "pace"]\n'})}),"\n",(0,i.jsx)(n.h2,{id:"writing-your-own-custom-filters",children:"Writing your own custom filters"}),"\n",(0,i.jsxs)(n.p,{children:["You can write your own filters from scratch although we must warn you that it is not trivial\nbecause it requires a good knowledge of Elasticsearch and studying the mapping defined in the\n",(0,i.jsx)(n.a,{href:"https://github.com/openfun/richie/blob/master/src/richie/apps/search/indexers/courses.py",children:"courses indexer"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["A filter is a class deriving from ",(0,i.jsx)(n.a,{href:"https://github.com/openfun/richie/blob/master/src/richie/apps/search/filter_definitions/base.py",children:"BaseFilterDefinition"})," and defining methods to return the\ninformation to display the filter and query fragments for elasticsearch:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"get_form_fields"}),": returns the form field instance that will be used to parse and validate this\nfilter's values from the querystring"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"get_query_fragment"}),": returns the query fragment to use as filter in ElasticSearch"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"get_aggs_fragment"}),": returns the query fragment to use to extract facets from\nElasticSearch aggregations"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"get_facet_info"}),": returns the dynamic facet information from a filter's Elasticsearch facet\nresults. Together with the facet's static information, it will be used to display the filter\nin its current status in the left side panel of the search page."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["We will not go into more details here about how filter definition classes work, but you can refer\nto the code of the existing filters as good examples of what is possible. The code, although not\ntrivial, was given much care and includes many comments in an attempt to help writing new custom\nfilters. Of course, don't hesitate to ask for help by\n",(0,i.jsx)(n.a,{href:"https://github.com/openfun/richie/issues",children:"opening an issue"}),"!"]})]})}function d(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(h,{...e})}):h(e)}},11151:(e,n,t)=>{t.d(n,{Z:()=>o,a:()=>a});var i=t(67294);const s={},r=i.createContext(s);function a(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/07dcad66.3f781cbb.js b/assets/js/07dcad66.3f781cbb.js deleted file mode 100644 index 32fc1f4c04..0000000000 --- a/assets/js/07dcad66.3f781cbb.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[64049],{94712:(e,t,o)=>{o.r(t),o.d(t,{assets:()=>a,contentTitle:()=>s,default:()=>h,frontMatter:()=>n,metadata:()=>c,toc:()=>l});var i=o(85893),r=o(11151);const n={id:"cookiecutter",title:"Start your own site",sidebar_label:"Start your own site"},s=void 0,c={id:"cookiecutter",title:"Start your own site",description:"We use Cookiecutter to help you",source:"@site/versioned_docs/version-2.25.0-beta.0/cookiecutter.md",sourceDirName:".",slug:"/cookiecutter",permalink:"/docs/2.25.0-beta.0/cookiecutter",draft:!1,unlisted:!1,tags:[],version:"2.25.0-beta.0",lastUpdatedBy:"jbpenrath",lastUpdatedAt:1704387937,formattedLastUpdatedAt:"Jan 4, 2024",frontMatter:{id:"cookiecutter",title:"Start your own site",sidebar_label:"Start your own site"},sidebar:"docs",previous:{title:"Discover Richie",permalink:"/docs/2.25.0-beta.0/discover"},next:{title:"Search filters customization",permalink:"/docs/2.25.0-beta.0/filters-customization"}},a={},l=[{value:"Run Cookiecutter",id:"run-cookiecutter",level:2},{value:"Bootstrap your project",id:"bootstrap-your-project",level:3},{value:"Theming",id:"theming",level:2},{value:"Update your Richie site factory",id:"update-your-richie-site-factory",level:2},{value:"Help us improve this project",id:"help-us-improve-this-project",level:2}];function d(e){const t={a:"a",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(t.p,{children:["We use ",(0,i.jsx)(t.a,{href:"https://github.com/audreyr/cookiecutter",children:"Cookiecutter"})," to help you\nset up a production-ready learning portal website based on\n",(0,i.jsx)(t.a,{href:"https://github.com/openfun/richie",children:"Richie"})," in seconds."]}),"\n",(0,i.jsx)(t.h2,{id:"run-cookiecutter",children:"Run Cookiecutter"}),"\n",(0,i.jsx)(t.p,{children:"There are 2 options to run Cookiecutter:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://cookiecutter.readthedocs.io/en/latest/installation.html",children:"install it on your machine"})}),"\n",(0,i.jsx)(t.li,{children:"run it with Docker"}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"While you think of it, navigate to the directory in which you want to create\nyour site factory:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{children:"cd /path/to/your/code/directory\n"})}),"\n",(0,i.jsxs)(t.p,{children:["If you chose to install Cookiecutter, you can now run it against our\n",(0,i.jsx)(t.a,{href:"https://github.com/openfun/richie/tree/master/cookiecutter",children:"template"})," as follows:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"cookiecutter gh:openfun/richie --directory cookiecutter --checkout v2.25.0-beta.0\n"})}),"\n",(0,i.jsxs)(t.p,{children:["If you didn't want to install it on your machine, we provide a Docker image\nbuilt with our ",(0,i.jsx)(t.a,{href:"https://github.com/openfun/dockerfiles",children:"own repository"})," that you can use as follows:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"docker run --rm -it -u $(id -u):$(id -g) -v $PWD:/app \\\nfundocker/cookiecutter gh:openfun/richie --directory cookiecutter --checkout v2.25.0-beta.0\n"})}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"--directory"})," option is to indicate that our Cookiecutter template is in\na ",(0,i.jsx)(t.code,{children:"cookiecutter"})," directory inside our git repository and not at the root."]}),"\n",(0,i.jsxs)(t.p,{children:['You will be prompted to enter an organization name, which will determine the\nname of your repository. For example, if you choose "foo" as organization\nname, your repository will be named ',(0,i.jsx)(t.code,{children:"foo-richie-site-factory"}),". It's\nnice if you keep it that way so all richie site factories follow this\nconvention."]}),"\n",(0,i.jsx)(t.p,{children:"When you confirm the organization name, Cookiecutter will generate your\nproject from the Cookiecutter template and place it at the level where you\ncurrently are."}),"\n",(0,i.jsx)(t.h3,{id:"bootstrap-your-project",children:"Bootstrap your project"}),"\n",(0,i.jsx)(t.p,{children:"Enter the newly created project and add a new site to your site factory:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"cd foo-richie-site-factory\nmake add-site\n"})}),"\n",(0,i.jsxs)(t.p,{children:["This script also uses Cookiecutter against our ",(0,i.jsx)(t.a,{href:"https://github.com/openfun/richie/tree/master/cookiecutter/%7B%7Bcookiecutter.organization%7D%7D-richie-site-factory/template",children:"site template"}),"."]}),"\n",(0,i.jsx)(t.p,{children:"Once your new site is created, activate it:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"bin/activate\n"})}),"\n",(0,i.jsx)(t.p,{children:"Now bootstrap the site to build its docker image, create its media folder,\ndatabase, etc.:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"make bootstrap\n"})}),"\n",(0,i.jsxs)(t.p,{children:["Once the bootstrap phase is finished, you should be able to view the site at\n",(0,i.jsx)(t.a,{href:"http://localhost:8070",children:"localhost:8070"}),"."]}),"\n",(0,i.jsx)(t.p,{children:"You can create a full fledge demo to test your site by running:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"make demo-site\n"})}),"\n",(0,i.jsx)(t.p,{children:"Note that the README of your newly created site factory contains detailed\ninformation about how to configure and run a site."}),"\n",(0,i.jsx)(t.p,{children:"Once you're happy with your site, don't forget to backup your work e.g. by\ncommitting it and pushing it to a new git repository."}),"\n",(0,i.jsx)(t.h2,{id:"theming",children:"Theming"}),"\n",(0,i.jsx)(t.p,{children:"You probably want to change the default theme. The cookiecutter adds an extra scss frontend folder with a couple of templates that you can use to change the default styling of the site."}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.code,{children:"sites//src/frontend/scss/extras/colors/_palette.scss"})}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.code,{children:"sites//src/frontend/scss/extras/colors/_theme.scss"})}),"\n"]}),"\n",(0,i.jsxs)(t.p,{children:["To change the default logo of the site, you need to create the folder ",(0,i.jsx)(t.code,{children:"sites//src/backend/base/static/richie/images"})," and then override the new ",(0,i.jsx)(t.code,{children:"logo.png"})," picture."]}),"\n",(0,i.jsx)(t.p,{children:"For more advanced customization, refer to our recipes:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"/docs/filters-customization",children:"How to customize search filters"})}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"/docs/frontend-overrides",children:"How to override frontend components in Richie"})}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"update-your-richie-site-factory",children:"Update your Richie site factory"}),"\n",(0,i.jsxs)(t.p,{children:["If we later improve our scripts, you will be able to update your own site\nfactory by replaying Cookiecutter. This will override your files in the\nproject's scaffolding but, don't worry, it will respect all the sites you\nwill have created in the ",(0,i.jsx)(t.code,{children:"sites"})," directory:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{children:"cookiecutter --overwrite-if-exists gh:openfun/richie --directory=cookiecutter\n"})}),"\n",(0,i.jsx)(t.h2,{id:"help-us-improve-this-project",children:"Help us improve this project"}),"\n",(0,i.jsx)(t.p,{children:"After starting your project, please submit an issue let us know how it went and\nwhat other features we should add to make it better."})]})}function h(e={}){const{wrapper:t}={...(0,r.a)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},11151:(e,t,o)=>{o.d(t,{Z:()=>c,a:()=>s});var i=o(67294);const r={},n=i.createContext(r);function s(e){const t=i.useContext(n);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),i.createElement(n.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/07dcad66.ddf2d91a.js b/assets/js/07dcad66.ddf2d91a.js new file mode 100644 index 0000000000..855238f4a2 --- /dev/null +++ b/assets/js/07dcad66.ddf2d91a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[64049],{94712:(e,t,o)=>{o.r(t),o.d(t,{assets:()=>a,contentTitle:()=>s,default:()=>h,frontMatter:()=>n,metadata:()=>c,toc:()=>l});var i=o(85893),r=o(11151);const n={id:"cookiecutter",title:"Start your own site",sidebar_label:"Start your own site"},s=void 0,c={id:"cookiecutter",title:"Start your own site",description:"We use Cookiecutter to help you",source:"@site/versioned_docs/version-2.25.0-beta.0/cookiecutter.md",sourceDirName:".",slug:"/cookiecutter",permalink:"/docs/2.25.0-beta.0/cookiecutter",draft:!1,unlisted:!1,tags:[],version:"2.25.0-beta.0",lastUpdatedBy:"jbpenrath",lastUpdatedAt:1704387937e3,frontMatter:{id:"cookiecutter",title:"Start your own site",sidebar_label:"Start your own site"},sidebar:"docs",previous:{title:"Discover Richie",permalink:"/docs/2.25.0-beta.0/discover"},next:{title:"Search filters customization",permalink:"/docs/2.25.0-beta.0/filters-customization"}},a={},l=[{value:"Run Cookiecutter",id:"run-cookiecutter",level:2},{value:"Bootstrap your project",id:"bootstrap-your-project",level:3},{value:"Theming",id:"theming",level:2},{value:"Update your Richie site factory",id:"update-your-richie-site-factory",level:2},{value:"Help us improve this project",id:"help-us-improve-this-project",level:2}];function d(e){const t={a:"a",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(t.p,{children:["We use ",(0,i.jsx)(t.a,{href:"https://github.com/audreyr/cookiecutter",children:"Cookiecutter"})," to help you\nset up a production-ready learning portal website based on\n",(0,i.jsx)(t.a,{href:"https://github.com/openfun/richie",children:"Richie"})," in seconds."]}),"\n",(0,i.jsx)(t.h2,{id:"run-cookiecutter",children:"Run Cookiecutter"}),"\n",(0,i.jsx)(t.p,{children:"There are 2 options to run Cookiecutter:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://cookiecutter.readthedocs.io/en/latest/installation.html",children:"install it on your machine"})}),"\n",(0,i.jsx)(t.li,{children:"run it with Docker"}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"While you think of it, navigate to the directory in which you want to create\nyour site factory:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{children:"cd /path/to/your/code/directory\n"})}),"\n",(0,i.jsxs)(t.p,{children:["If you chose to install Cookiecutter, you can now run it against our\n",(0,i.jsx)(t.a,{href:"https://github.com/openfun/richie/tree/master/cookiecutter",children:"template"})," as follows:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"cookiecutter gh:openfun/richie --directory cookiecutter --checkout v2.25.0-beta.0\n"})}),"\n",(0,i.jsxs)(t.p,{children:["If you didn't want to install it on your machine, we provide a Docker image\nbuilt with our ",(0,i.jsx)(t.a,{href:"https://github.com/openfun/dockerfiles",children:"own repository"})," that you can use as follows:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"docker run --rm -it -u $(id -u):$(id -g) -v $PWD:/app \\\nfundocker/cookiecutter gh:openfun/richie --directory cookiecutter --checkout v2.25.0-beta.0\n"})}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"--directory"})," option is to indicate that our Cookiecutter template is in\na ",(0,i.jsx)(t.code,{children:"cookiecutter"})," directory inside our git repository and not at the root."]}),"\n",(0,i.jsxs)(t.p,{children:['You will be prompted to enter an organization name, which will determine the\nname of your repository. For example, if you choose "foo" as organization\nname, your repository will be named ',(0,i.jsx)(t.code,{children:"foo-richie-site-factory"}),". It's\nnice if you keep it that way so all richie site factories follow this\nconvention."]}),"\n",(0,i.jsx)(t.p,{children:"When you confirm the organization name, Cookiecutter will generate your\nproject from the Cookiecutter template and place it at the level where you\ncurrently are."}),"\n",(0,i.jsx)(t.h3,{id:"bootstrap-your-project",children:"Bootstrap your project"}),"\n",(0,i.jsx)(t.p,{children:"Enter the newly created project and add a new site to your site factory:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"cd foo-richie-site-factory\nmake add-site\n"})}),"\n",(0,i.jsxs)(t.p,{children:["This script also uses Cookiecutter against our ",(0,i.jsx)(t.a,{href:"https://github.com/openfun/richie/tree/master/cookiecutter/%7B%7Bcookiecutter.organization%7D%7D-richie-site-factory/template",children:"site template"}),"."]}),"\n",(0,i.jsx)(t.p,{children:"Once your new site is created, activate it:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"bin/activate\n"})}),"\n",(0,i.jsx)(t.p,{children:"Now bootstrap the site to build its docker image, create its media folder,\ndatabase, etc.:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"make bootstrap\n"})}),"\n",(0,i.jsxs)(t.p,{children:["Once the bootstrap phase is finished, you should be able to view the site at\n",(0,i.jsx)(t.a,{href:"http://localhost:8070",children:"localhost:8070"}),"."]}),"\n",(0,i.jsx)(t.p,{children:"You can create a full fledge demo to test your site by running:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"make demo-site\n"})}),"\n",(0,i.jsx)(t.p,{children:"Note that the README of your newly created site factory contains detailed\ninformation about how to configure and run a site."}),"\n",(0,i.jsx)(t.p,{children:"Once you're happy with your site, don't forget to backup your work e.g. by\ncommitting it and pushing it to a new git repository."}),"\n",(0,i.jsx)(t.h2,{id:"theming",children:"Theming"}),"\n",(0,i.jsx)(t.p,{children:"You probably want to change the default theme. The cookiecutter adds an extra scss frontend folder with a couple of templates that you can use to change the default styling of the site."}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.code,{children:"sites//src/frontend/scss/extras/colors/_palette.scss"})}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.code,{children:"sites//src/frontend/scss/extras/colors/_theme.scss"})}),"\n"]}),"\n",(0,i.jsxs)(t.p,{children:["To change the default logo of the site, you need to create the folder ",(0,i.jsx)(t.code,{children:"sites//src/backend/base/static/richie/images"})," and then override the new ",(0,i.jsx)(t.code,{children:"logo.png"})," picture."]}),"\n",(0,i.jsx)(t.p,{children:"For more advanced customization, refer to our recipes:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"/docs/filters-customization",children:"How to customize search filters"})}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"/docs/frontend-overrides",children:"How to override frontend components in Richie"})}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"update-your-richie-site-factory",children:"Update your Richie site factory"}),"\n",(0,i.jsxs)(t.p,{children:["If we later improve our scripts, you will be able to update your own site\nfactory by replaying Cookiecutter. This will override your files in the\nproject's scaffolding but, don't worry, it will respect all the sites you\nwill have created in the ",(0,i.jsx)(t.code,{children:"sites"})," directory:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{children:"cookiecutter --overwrite-if-exists gh:openfun/richie --directory=cookiecutter\n"})}),"\n",(0,i.jsx)(t.h2,{id:"help-us-improve-this-project",children:"Help us improve this project"}),"\n",(0,i.jsx)(t.p,{children:"After starting your project, please submit an issue let us know how it went and\nwhat other features we should add to make it better."})]})}function h(e={}){const{wrapper:t}={...(0,r.a)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},11151:(e,t,o)=>{o.d(t,{Z:()=>c,a:()=>s});var i=o(67294);const r={},n=i.createContext(r);function s(e){const t=i.useContext(n);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),i.createElement(n.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/07f167f3.3765bd72.js b/assets/js/07f167f3.3765bd72.js new file mode 100644 index 0000000000..c2e4078bb3 --- /dev/null +++ b/assets/js/07f167f3.3765bd72.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[25541],{63871:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>l,toc:()=>d});var s=t(85893),i=t(11151);const a={id:"native-installation",title:"Installing Richie on your machine",sidebar_label:"Native installation"},r=void 0,l={id:"native-installation",title:"Installing Richie on your machine",description:"This document aims to list all needed steps to have a working Richie",source:"@site/versioned_docs/version-2.20.1/native-installation.md",sourceDirName:".",slug:"/native-installation",permalink:"/docs/2.20.1/native-installation",draft:!1,unlisted:!1,tags:[],version:"2.20.1",lastUpdatedBy:"jbpenrath",lastUpdatedAt:1677062183e3,frontMatter:{id:"native-installation",title:"Installing Richie on your machine",sidebar_label:"Native installation"},sidebar:"docs",previous:{title:"Docker development",permalink:"/docs/2.20.1/docker-development"},next:{title:"Contributing guide",permalink:"/docs/2.20.1/contributing-guide"}},o={},d=[{value:"Installing a fresh server",id:"installing-a-fresh-server",level:2},{value:"Version",id:"version",level:3},{value:"System update",id:"system-update",level:3},{value:"Database part",id:"database-part",level:2},{value:"Elasticsearch",id:"elasticsearch",level:2},{value:"Ubuntu",id:"ubuntu",level:3},{value:"OS X",id:"os-x",level:3},{value:"Application part",id:"application-part",level:2},{value:"Python and other requirements",id:"python-and-other-requirements",level:3},{value:"The virtualenv",id:"the-virtualenv",level:3},{value:"Frontend build",id:"frontend-build",level:3},{value:"Run server",id:"run-server",level:3}];function c(e){const n={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(n.p,{children:["This document aims to list all needed steps to have a working ",(0,s.jsx)(n.code,{children:"Richie"}),"\ninstallation on your laptop."]}),"\n",(0,s.jsxs)(n.p,{children:["A better approach is to use ",(0,s.jsx)(n.a,{href:"https://docs.docker.com",children:(0,s.jsx)(n.code,{children:"Docker"})})," as explained in\nour guide for ",(0,s.jsx)(n.a,{href:"/docs/2.20.1/installation",children:"container-native installation"})," instructions."]}),"\n",(0,s.jsx)(n.h2,{id:"installing-a-fresh-server",children:"Installing a fresh server"}),"\n",(0,s.jsx)(n.h3,{id:"version",children:"Version"}),"\n",(0,s.jsxs)(n.p,{children:["You need a ",(0,s.jsx)(n.code,{children:"Ubuntu 18.04 Bionic Beaver"})," (the latest LTS version) fresh\ninstallation."]}),"\n",(0,s.jsxs)(n.p,{children:["If you are using another operating system or distribution, you can use\n",(0,s.jsx)(n.a,{href:"https://docs.vagrantup.com/v2/getting-started/index.html",children:(0,s.jsx)(n.code,{children:"Vagrant"})})," to get a\nrunning Ubuntu 18.04 server in seconds."]}),"\n",(0,s.jsx)(n.h3,{id:"system-update",children:"System update"}),"\n",(0,s.jsx)(n.p,{children:"Be sure to have fresh packages on the server (kernel, libc, ssl patches...):\npost"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"sudo apt-get -y update\nsudo apt-get -y dist-upgrade\n"})}),"\n",(0,s.jsx)(n.h2,{id:"database-part",children:"Database part"}),"\n",(0,s.jsxs)(n.p,{children:["You must first install ",(0,s.jsx)(n.code,{children:"postgresql"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"// On Linux\nsudo apt-get -y install postgresql\n\n// On OS X\nbrew install postgresql@10\nbrew services start postgresql@10\n// don't forget to add your new postgres install to the $PATH\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Postgresql"})," is now running."]}),"\n",(0,s.jsxs)(n.p,{children:["Then you can create the database owner and the database itself, using the\n",(0,s.jsx)(n.code,{children:"postgres"})," user:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"sudo -u postgres -i // skip this on OS X as the default install will use your local user\ncreateuser fun -sP\n"})}),"\n",(0,s.jsx)(n.p,{children:"Note: we created the user as a superuser. This should only be done in dev/test\nenvironments."}),"\n",(0,s.jsx)(n.p,{children:"Now, create the database with this user:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"createdb richie -O fun -W\nexit\n"})}),"\n",(0,s.jsx)(n.h2,{id:"elasticsearch",children:"Elasticsearch"}),"\n",(0,s.jsx)(n.h3,{id:"ubuntu",children:"Ubuntu"}),"\n",(0,s.jsx)(n.p,{children:"Download and install the Public Signing Key"}),"\n",(0,s.jsxs)(n.p,{children:["$ wget -qO - ",(0,s.jsx)(n.a,{href:"https://artifacts.elastic.co/GPG-KEY-elasticsearch",children:"https://artifacts.elastic.co/GPG-KEY-elasticsearch"})," | sudo apt-key add -"]}),"\n",(0,s.jsx)(n.p,{children:"You may need to install the apt-transport-https package on Debian before\nproceeding:"}),"\n",(0,s.jsx)(n.p,{children:"$ sudo apt-get install apt-transport-https"}),"\n",(0,s.jsx)(n.p,{children:"Save the repository definition to /etc/apt/sources.list.d/elastic-6.3.1.list:"}),"\n",(0,s.jsxs)(n.p,{children:['$ echo "deb ',(0,s.jsx)(n.a,{href:"https://artifacts.elastic.co/packages/6.3.1/apt",children:"https://artifacts.elastic.co/packages/6.3.1/apt"}),' stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-6.3.1.list']}),"\n",(0,s.jsx)(n.p,{children:"Update repository and install"}),"\n",(0,s.jsx)(n.p,{children:"$ sudo apt-get update\n$ sudo apt-get install elasticsearch\n$ sudo /etc/init.d/elasticsearch start"}),"\n",(0,s.jsx)(n.h3,{id:"os-x",children:"OS X"}),"\n",(0,s.jsx)(n.p,{children:"$ brew install elasticsearch"}),"\n",(0,s.jsx)(n.h2,{id:"application-part",children:"Application part"}),"\n",(0,s.jsx)(n.h3,{id:"python-and-other-requirements",children:"Python and other requirements"}),"\n",(0,s.jsxs)(n.p,{children:["We use ",(0,s.jsx)(n.code,{children:"Python 3.6"})," which is the one installed by default in ",(0,s.jsx)(n.code,{children:"Ubuntu 18.04"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["You can install it on OS X using the following commands. Make sure to always run\n",(0,s.jsx)(n.code,{children:"python3"})," instead of ",(0,s.jsx)(n.code,{children:"python"})," and ",(0,s.jsx)(n.code,{children:"pip3"})," instead of ",(0,s.jsx)(n.code,{children:"pip"})," to ensure the correct\nversion of Python (your homebrew install of 3) is used."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"brew install python3\nbrew postinstall python3\n"})}),"\n",(0,s.jsx)(n.h3,{id:"the-virtualenv",children:"The virtualenv"}),"\n",(0,s.jsxs)(n.p,{children:["Place yourself in the application directory ",(0,s.jsx)(n.code,{children:"app"}),":"]}),"\n",(0,s.jsx)(n.p,{children:"cd app"}),"\n",(0,s.jsx)(n.p,{children:"We choose to run our application in a virtual environment."}),"\n",(0,s.jsxs)(n.p,{children:["For this, we'll install ",(0,s.jsx)(n.code,{children:"virtualenvwrapper"})," and add an environment:"]}),"\n",(0,s.jsx)(n.p,{children:"pip install virtualenvwrapper"}),"\n",(0,s.jsx)(n.p,{children:"You can open a new shell to activate the virtualenvwrapper commands, or simply\ndo:"}),"\n",(0,s.jsx)(n.p,{children:"source $(which virtualenvwrapper.sh)"}),"\n",(0,s.jsxs)(n.p,{children:["Then create the virtual environment for ",(0,s.jsx)(n.code,{children:"richie"}),":"]}),"\n",(0,s.jsx)(n.p,{children:"mkvirtualenv richie --no-site-packages --python=python3"}),"\n",(0,s.jsx)(n.p,{children:"The virtualenv should now be activated and you can install the Python\ndependencies for development:"}),"\n",(0,s.jsx)(n.p,{children:"pip install -e .[dev]"}),"\n",(0,s.jsx)(n.p,{children:'The "dev.txt" requirement file installs packages specific to a dev environment\nand should not be used in production.'}),"\n",(0,s.jsx)(n.h3,{id:"frontend-build",children:"Frontend build"}),"\n",(0,s.jsx)(n.p,{children:"This project is a hybrid that uses both Django generated pages and frontend JS\ncode. As such, it includes a frontend build process that comes in two parts: JS\n& CSS."}),"\n",(0,s.jsxs)(n.p,{children:["We need NPM to install the dependencies and run the build, which depends on a\nversion of Nodejs specified in ",(0,s.jsx)(n.code,{children:".nvmrc"}),". See ",(0,s.jsx)(n.a,{href:"https://github.com/creationix/nvm",children:"the\nrepo"})," for instructions on how to install NVM.\nTo take advantage of ",(0,s.jsx)(n.code,{children:".nvmrc"}),", run this in the context of the repository:"]}),"\n",(0,s.jsx)(n.p,{children:"nvm install\nnvm use"}),"\n",(0,s.jsxs)(n.p,{children:["As a prerequisite to running the frontend build for either JS or CSS, you'll\nneed to ",(0,s.jsx)(n.a,{href:"https://yarnpkg.com/lang/en/docs/install/",children:"install yarn"})," and download\ndependencies ",(0,s.jsx)(n.em,{children:"via"}),":"]}),"\n",(0,s.jsx)(n.p,{children:"yarn install"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"JS build"}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"npm run build\n"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"CSS build"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"This will compile all our SCSS files into one bundle and put it in the static\nfolder we're serving."}),"\n",(0,s.jsx)(n.p,{children:"npm run sass"}),"\n",(0,s.jsx)(n.h3,{id:"run-server",children:"Run server"}),"\n",(0,s.jsx)(n.p,{children:"Make sure your database is up-to-date before running the application the first\ntime and after each modification to your models:"}),"\n",(0,s.jsx)(n.p,{children:"python sandbox/manage.py migrate"}),"\n",(0,s.jsx)(n.p,{children:"You can create a superuser account:"}),"\n",(0,s.jsx)(n.p,{children:"python sandbox/manage.py createsuperuser"}),"\n",(0,s.jsx)(n.p,{children:"Run the tests"}),"\n",(0,s.jsx)(n.p,{children:"python sandbox/manage.py test"}),"\n",(0,s.jsxs)(n.p,{children:["You should now be able to start Django and view the site at\n",(0,s.jsx)(n.a,{href:"http://localhost:8000",children:"localhost:8000"})]}),"\n",(0,s.jsx)(n.p,{children:"python sandbox/manage.py runserver"})]})}function h(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},11151:(e,n,t)=>{t.d(n,{Z:()=>l,a:()=>r});var s=t(67294);const i={},a=s.createContext(i);function r(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/07f167f3.970290a6.js b/assets/js/07f167f3.970290a6.js deleted file mode 100644 index 218d8962e2..0000000000 --- a/assets/js/07f167f3.970290a6.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[25541],{63871:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>l,toc:()=>d});var s=t(85893),i=t(11151);const a={id:"native-installation",title:"Installing Richie on your machine",sidebar_label:"Native installation"},r=void 0,l={id:"native-installation",title:"Installing Richie on your machine",description:"This document aims to list all needed steps to have a working Richie",source:"@site/versioned_docs/version-2.20.1/native-installation.md",sourceDirName:".",slug:"/native-installation",permalink:"/docs/2.20.1/native-installation",draft:!1,unlisted:!1,tags:[],version:"2.20.1",lastUpdatedBy:"jbpenrath",lastUpdatedAt:1677062183,formattedLastUpdatedAt:"Feb 22, 2023",frontMatter:{id:"native-installation",title:"Installing Richie on your machine",sidebar_label:"Native installation"},sidebar:"docs",previous:{title:"Docker development",permalink:"/docs/2.20.1/docker-development"},next:{title:"Contributing guide",permalink:"/docs/2.20.1/contributing-guide"}},o={},d=[{value:"Installing a fresh server",id:"installing-a-fresh-server",level:2},{value:"Version",id:"version",level:3},{value:"System update",id:"system-update",level:3},{value:"Database part",id:"database-part",level:2},{value:"Elasticsearch",id:"elasticsearch",level:2},{value:"Ubuntu",id:"ubuntu",level:3},{value:"OS X",id:"os-x",level:3},{value:"Application part",id:"application-part",level:2},{value:"Python and other requirements",id:"python-and-other-requirements",level:3},{value:"The virtualenv",id:"the-virtualenv",level:3},{value:"Frontend build",id:"frontend-build",level:3},{value:"Run server",id:"run-server",level:3}];function c(e){const n={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(n.p,{children:["This document aims to list all needed steps to have a working ",(0,s.jsx)(n.code,{children:"Richie"}),"\ninstallation on your laptop."]}),"\n",(0,s.jsxs)(n.p,{children:["A better approach is to use ",(0,s.jsx)(n.a,{href:"https://docs.docker.com",children:(0,s.jsx)(n.code,{children:"Docker"})})," as explained in\nour guide for ",(0,s.jsx)(n.a,{href:"/docs/2.20.1/installation",children:"container-native installation"})," instructions."]}),"\n",(0,s.jsx)(n.h2,{id:"installing-a-fresh-server",children:"Installing a fresh server"}),"\n",(0,s.jsx)(n.h3,{id:"version",children:"Version"}),"\n",(0,s.jsxs)(n.p,{children:["You need a ",(0,s.jsx)(n.code,{children:"Ubuntu 18.04 Bionic Beaver"})," (the latest LTS version) fresh\ninstallation."]}),"\n",(0,s.jsxs)(n.p,{children:["If you are using another operating system or distribution, you can use\n",(0,s.jsx)(n.a,{href:"https://docs.vagrantup.com/v2/getting-started/index.html",children:(0,s.jsx)(n.code,{children:"Vagrant"})})," to get a\nrunning Ubuntu 18.04 server in seconds."]}),"\n",(0,s.jsx)(n.h3,{id:"system-update",children:"System update"}),"\n",(0,s.jsx)(n.p,{children:"Be sure to have fresh packages on the server (kernel, libc, ssl patches...):\npost"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"sudo apt-get -y update\nsudo apt-get -y dist-upgrade\n"})}),"\n",(0,s.jsx)(n.h2,{id:"database-part",children:"Database part"}),"\n",(0,s.jsxs)(n.p,{children:["You must first install ",(0,s.jsx)(n.code,{children:"postgresql"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"// On Linux\nsudo apt-get -y install postgresql\n\n// On OS X\nbrew install postgresql@10\nbrew services start postgresql@10\n// don't forget to add your new postgres install to the $PATH\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Postgresql"})," is now running."]}),"\n",(0,s.jsxs)(n.p,{children:["Then you can create the database owner and the database itself, using the\n",(0,s.jsx)(n.code,{children:"postgres"})," user:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"sudo -u postgres -i // skip this on OS X as the default install will use your local user\ncreateuser fun -sP\n"})}),"\n",(0,s.jsx)(n.p,{children:"Note: we created the user as a superuser. This should only be done in dev/test\nenvironments."}),"\n",(0,s.jsx)(n.p,{children:"Now, create the database with this user:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"createdb richie -O fun -W\nexit\n"})}),"\n",(0,s.jsx)(n.h2,{id:"elasticsearch",children:"Elasticsearch"}),"\n",(0,s.jsx)(n.h3,{id:"ubuntu",children:"Ubuntu"}),"\n",(0,s.jsx)(n.p,{children:"Download and install the Public Signing Key"}),"\n",(0,s.jsxs)(n.p,{children:["$ wget -qO - ",(0,s.jsx)(n.a,{href:"https://artifacts.elastic.co/GPG-KEY-elasticsearch",children:"https://artifacts.elastic.co/GPG-KEY-elasticsearch"})," | sudo apt-key add -"]}),"\n",(0,s.jsx)(n.p,{children:"You may need to install the apt-transport-https package on Debian before\nproceeding:"}),"\n",(0,s.jsx)(n.p,{children:"$ sudo apt-get install apt-transport-https"}),"\n",(0,s.jsx)(n.p,{children:"Save the repository definition to /etc/apt/sources.list.d/elastic-6.3.1.list:"}),"\n",(0,s.jsxs)(n.p,{children:['$ echo "deb ',(0,s.jsx)(n.a,{href:"https://artifacts.elastic.co/packages/6.3.1/apt",children:"https://artifacts.elastic.co/packages/6.3.1/apt"}),' stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-6.3.1.list']}),"\n",(0,s.jsx)(n.p,{children:"Update repository and install"}),"\n",(0,s.jsx)(n.p,{children:"$ sudo apt-get update\n$ sudo apt-get install elasticsearch\n$ sudo /etc/init.d/elasticsearch start"}),"\n",(0,s.jsx)(n.h3,{id:"os-x",children:"OS X"}),"\n",(0,s.jsx)(n.p,{children:"$ brew install elasticsearch"}),"\n",(0,s.jsx)(n.h2,{id:"application-part",children:"Application part"}),"\n",(0,s.jsx)(n.h3,{id:"python-and-other-requirements",children:"Python and other requirements"}),"\n",(0,s.jsxs)(n.p,{children:["We use ",(0,s.jsx)(n.code,{children:"Python 3.6"})," which is the one installed by default in ",(0,s.jsx)(n.code,{children:"Ubuntu 18.04"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["You can install it on OS X using the following commands. Make sure to always run\n",(0,s.jsx)(n.code,{children:"python3"})," instead of ",(0,s.jsx)(n.code,{children:"python"})," and ",(0,s.jsx)(n.code,{children:"pip3"})," instead of ",(0,s.jsx)(n.code,{children:"pip"})," to ensure the correct\nversion of Python (your homebrew install of 3) is used."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"brew install python3\nbrew postinstall python3\n"})}),"\n",(0,s.jsx)(n.h3,{id:"the-virtualenv",children:"The virtualenv"}),"\n",(0,s.jsxs)(n.p,{children:["Place yourself in the application directory ",(0,s.jsx)(n.code,{children:"app"}),":"]}),"\n",(0,s.jsx)(n.p,{children:"cd app"}),"\n",(0,s.jsx)(n.p,{children:"We choose to run our application in a virtual environment."}),"\n",(0,s.jsxs)(n.p,{children:["For this, we'll install ",(0,s.jsx)(n.code,{children:"virtualenvwrapper"})," and add an environment:"]}),"\n",(0,s.jsx)(n.p,{children:"pip install virtualenvwrapper"}),"\n",(0,s.jsx)(n.p,{children:"You can open a new shell to activate the virtualenvwrapper commands, or simply\ndo:"}),"\n",(0,s.jsx)(n.p,{children:"source $(which virtualenvwrapper.sh)"}),"\n",(0,s.jsxs)(n.p,{children:["Then create the virtual environment for ",(0,s.jsx)(n.code,{children:"richie"}),":"]}),"\n",(0,s.jsx)(n.p,{children:"mkvirtualenv richie --no-site-packages --python=python3"}),"\n",(0,s.jsx)(n.p,{children:"The virtualenv should now be activated and you can install the Python\ndependencies for development:"}),"\n",(0,s.jsx)(n.p,{children:"pip install -e .[dev]"}),"\n",(0,s.jsx)(n.p,{children:'The "dev.txt" requirement file installs packages specific to a dev environment\nand should not be used in production.'}),"\n",(0,s.jsx)(n.h3,{id:"frontend-build",children:"Frontend build"}),"\n",(0,s.jsx)(n.p,{children:"This project is a hybrid that uses both Django generated pages and frontend JS\ncode. As such, it includes a frontend build process that comes in two parts: JS\n& CSS."}),"\n",(0,s.jsxs)(n.p,{children:["We need NPM to install the dependencies and run the build, which depends on a\nversion of Nodejs specified in ",(0,s.jsx)(n.code,{children:".nvmrc"}),". See ",(0,s.jsx)(n.a,{href:"https://github.com/creationix/nvm",children:"the\nrepo"})," for instructions on how to install NVM.\nTo take advantage of ",(0,s.jsx)(n.code,{children:".nvmrc"}),", run this in the context of the repository:"]}),"\n",(0,s.jsx)(n.p,{children:"nvm install\nnvm use"}),"\n",(0,s.jsxs)(n.p,{children:["As a prerequisite to running the frontend build for either JS or CSS, you'll\nneed to ",(0,s.jsx)(n.a,{href:"https://yarnpkg.com/lang/en/docs/install/",children:"install yarn"})," and download\ndependencies ",(0,s.jsx)(n.em,{children:"via"}),":"]}),"\n",(0,s.jsx)(n.p,{children:"yarn install"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"JS build"}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"npm run build\n"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"CSS build"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"This will compile all our SCSS files into one bundle and put it in the static\nfolder we're serving."}),"\n",(0,s.jsx)(n.p,{children:"npm run sass"}),"\n",(0,s.jsx)(n.h3,{id:"run-server",children:"Run server"}),"\n",(0,s.jsx)(n.p,{children:"Make sure your database is up-to-date before running the application the first\ntime and after each modification to your models:"}),"\n",(0,s.jsx)(n.p,{children:"python sandbox/manage.py migrate"}),"\n",(0,s.jsx)(n.p,{children:"You can create a superuser account:"}),"\n",(0,s.jsx)(n.p,{children:"python sandbox/manage.py createsuperuser"}),"\n",(0,s.jsx)(n.p,{children:"Run the tests"}),"\n",(0,s.jsx)(n.p,{children:"python sandbox/manage.py test"}),"\n",(0,s.jsxs)(n.p,{children:["You should now be able to start Django and view the site at\n",(0,s.jsx)(n.a,{href:"http://localhost:8000",children:"localhost:8000"})]}),"\n",(0,s.jsx)(n.p,{children:"python sandbox/manage.py runserver"})]})}function h(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},11151:(e,n,t)=>{t.d(n,{Z:()=>l,a:()=>r});var s=t(67294);const i={},a=s.createContext(i);function r(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/08cf9976.47182207.js b/assets/js/08cf9976.47182207.js new file mode 100644 index 0000000000..7103f978e3 --- /dev/null +++ b/assets/js/08cf9976.47182207.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkrichie_education_docs=self.webpackChunkrichie_education_docs||[]).push([[10899],{69933:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>c,toc:()=>r});var s=i(85893),t=i(11151);const o={id:"web-analytics",title:"Add web analytics to your site",sidebar_label:"Web Analytics"},a=void 0,c={id:"web-analytics",title:"Add web analytics to your site",description:"Richie has native support to Google Analytics and Google Tag Manager Web Analytics solutions.",source:"@site/versioned_docs/version-2.14.1/web-analytics.md",sourceDirName:".",slug:"/web-analytics",permalink:"/docs/2.14.1/web-analytics",draft:!1,unlisted:!1,tags:[],version:"2.14.1",lastUpdatedBy:"Mehdi Benadda",lastUpdatedAt:1655108611e3,frontMatter:{id:"web-analytics",title:"Add web analytics to your site",sidebar_label:"Web Analytics"},sidebar:"docs",previous:{title:"LMS connection",permalink:"/docs/2.14.1/lms-connection"},next:{title:"Installation",permalink:"/docs/2.14.1/installation"}},l={},r=[{value:"Google Analytics",id:"google-analytics",level:2},{value:"Google Tag Manager",id:"google-tag-manager",level:2},{value:"Location of the web analytics javascript",id:"location-of-the-web-analytics-javascript",level:2},{value:"Add a new Web Analytics solution",id:"add-a-new-web-analytics-solution",level:2}];function d(e){const n={a:"a",code:"code",h2:"h2",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(n.p,{children:["Richie has native support to ",(0,s.jsx)(n.a,{href:"#google-analytics",children:"Google Analytics"})," and ",(0,s.jsx)(n.a,{href:"#google-tag-manager",children:"Google Tag Manager"})," Web Analytics solutions.\nThe purpose of this file is to explain how you can enable one of the supported Web Analytics providers\nand how you can extend Richie with an alternative solution."]}),"\n",(0,s.jsx)(n.h2,{id:"google-analytics",children:"Google Analytics"}),"\n",(0,s.jsxs)(n.p,{children:["Next, it is described how you can configure the ",(0,s.jsx)(n.strong,{children:"Google Analytics"})," on your Richie site."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Add the ",(0,s.jsx)(n.code,{children:"WEB_ANALYTICS_ID"})," setting, with your Google Analytics tracking id code."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The current Google Analytics implementation also includes custom dimensions. Those dimensions permit you to create further analyses on Google Analytics or even use them to create custom reports.\nCustom dimensions with a value as example:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Organizations codes - ",(0,s.jsx)(n.code,{children:"UNIV_LISBON | UNIV_PORTO"})]}),"\n",(0,s.jsxs)(n.li,{children:["Course code - ",(0,s.jsx)(n.code,{children:"COURSE_XPTO"})]}),"\n",(0,s.jsxs)(n.li,{children:["Course runs titles - ",(0,s.jsx)(n.code,{children:"Summer edition | Winter edition"})]}),"\n",(0,s.jsxs)(n.li,{children:["Course runs resource links - ",(0,s.jsx)(n.code,{children:"http://example.edx:8073/courses/course-v1:edX+DemoX+Demo_Course/info"})]}),"\n",(0,s.jsxs)(n.li,{children:["Page title - ",(0,s.jsx)(n.code,{children:"Introduction to Programming"})]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"google-tag-manager",children:"Google Tag Manager"}),"\n",(0,s.jsxs)(n.p,{children:["Next, it is described how you can configure the ",(0,s.jsx)(n.strong,{children:"Google Tag Manager"})," on your Richie site."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Add the ",(0,s.jsx)(n.code,{children:"WEB_ANALYTICS_ID"})," setting, with your Google Tag Manager tracking id code."]}),"\n",(0,s.jsxs)(n.li,{children:["Add the ",(0,s.jsx)(n.code,{children:"WEB_ANALYTICS_PROVIDER"})," setting with the ",(0,s.jsx)(n.code,{children:"google_tag_manager"})," value."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The current Google Tag Manager implementation also defines a custom dimensions like the ",(0,s.jsx)(n.a,{href:"#google-analytics",children:"Google Analytics"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"location-of-the-web-analytics-javascript",children:"Location of the web analytics javascript"}),"\n",(0,s.jsxs)(n.p,{children:["Use the ",(0,s.jsx)(n.code,{children:"WEB_ANALYTICS_LOCATION"})," settings to decide where do you want to put the Javascript code. Use ",(0,s.jsx)(n.code,{children:"head"})," (",(0,s.jsx)(n.strong,{children:"default"})," value), to put the Javascript on HTML header, or ",(0,s.jsx)(n.code,{children:"footer"}),", to put the Javascript code to the bottom of the body."]}),"\n",(0,s.jsx)(n.h2,{id:"add-a-new-web-analytics-solution",children:"Add a new Web Analytics solution"}),"\n",(0,s.jsx)(n.p,{children:"In this section it's described how you can add support to a different Web Analytics solution."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["override the ",(0,s.jsx)(n.code,{children:"richie/web_analytics.html"})," template"]}),"\n",(0,s.jsxs)(n.li,{children:["define the ",(0,s.jsx)(n.code,{children:"WEB_ANALYTICS_ID"})," setting with your tracking identification"]}),"\n",(0,s.jsxs)(n.li,{children:["define the ",(0,s.jsx)(n.code,{children:"WEB_ANALYTICS_PROVIDER"})," setting with a value that represents your solution, eg. ",(0,s.jsx)(n.code,{children:"my-custom-web-analytics-software"})]}),"\n",(0,s.jsxs)(n.li,{children:["optionally change ",(0,s.jsx)(n.code,{children:"WEB_ANALYTICS_LOCATION"})," setting with ",(0,s.jsx)(n.code,{children:"head"})," (default) or ",(0,s.jsx)(n.code,{children:"footer"})," value"]}),"\n"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Example of a ",(0,s.jsx)(n.code,{children:"richie/web_analytics.html"})," file customization that prints to the browser console log the dimension keys and values:"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-javascript",children:" - - + +Contributing guide | Richie + + -
Version: 1.12

Contributing guide

This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

+
Version: 1.12

Contributing guide

This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

Checking your code

@@ -37,6 +37,6 @@

Going further< bin/ directory:

bin
├── exec
├── pylint
├── pytest
└── run

More details and tips & tricks can be found in our development with Docker -documentation

+documentation

\ No newline at end of file diff --git a/docs/1.12/css-guidelines/index.html b/docs/1.12/css-guidelines/index.html index 86b352f9cc..809bb4a0bd 100644 --- a/docs/1.12/css-guidelines/index.html +++ b/docs/1.12/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
Version: 1.12

CSS Guidelines

The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

+
Version: 1.12

CSS Guidelines

The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

File structuration

Rules should be placed where their purpose is most apparent, and where they are easiest to find.

@@ -35,6 +35,6 @@

Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/1.12/discover/index.html b/docs/1.12/discover/index.html index cd492c3188..f13cca741a 100644 --- a/docs/1.12/discover/index.html +++ b/docs/1.12/discover/index.html @@ -2,13 +2,13 @@ - -Getting started with Richie | Richie - - + +Getting started with Richie | Richie + + -
    Version: 1.12

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    +
    Version: 1.12

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    Login/password are admin/admin. The database is regularly flushed.

    Architecture

    Richie is a container-native application but can also be installed @@ -48,6 +48,6 @@

    Adding conten

    Note that if you don't create the demo site and start from a blank CMS, you will get some errors requesting you to create some required root pages. So it is easier as a first approach to test the CMS with the demo site.

    -

    You should be able to view the site at localhost:8070

    +

    You should be able to view the site at localhost:8070

    \ No newline at end of file diff --git a/docs/1.12/django-react-interop/index.html b/docs/1.12/django-react-interop/index.html index f7ad8678ec..bcb2309402 100644 --- a/docs/1.12/django-react-interop/index.html +++ b/docs/1.12/django-react-interop/index.html @@ -2,19 +2,19 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 1.12

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 1.12

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Convention

    Therefore, we need a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the fun-react class and its modified children for this purpose.

    Example

    Here is how we would call a "FeaturedCourses" component from a template, a plugin or a snippet:

    -

    When our JS is loaded, it will recognize this as an element it must take over, and render the FeaturedCourses component in this element.

    +

    When our JS is loaded, it will recognize this as an element it must take over, and render the FeaturedCourses component in this element.

    \ No newline at end of file diff --git a/docs/1.12/docker-development/index.html b/docs/1.12/docker-development/index.html index df710a5b8f..56e6f562e6 100644 --- a/docs/1.12/docker-development/index.html +++ b/docs/1.12/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 1.12

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 1.12

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -75,6 +75,6 @@

    [1]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]

    In this case, increase virtual memory as follows (UNIX systems):

    -
    $ sudo sysctl -w vm/max_map_count=262144
    +
    $ sudo sysctl -w vm/max_map_count=262144
    \ No newline at end of file diff --git a/docs/1.12/native-installation/index.html b/docs/1.12/native-installation/index.html index 390f98639f..2258b3d6c9 100644 --- a/docs/1.12/native-installation/index.html +++ b/docs/1.12/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 1.12

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 1.12

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native instructions.

    @@ -108,6 +108,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/1.13/building-the-frontend/index.html b/docs/1.13/building-the-frontend/index.html index 3b2ee8f667..59c0b6e3ea 100644 --- a/docs/1.13/building-the-frontend/index.html +++ b/docs/1.13/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 1.13

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 1.13

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/1.13/contributing-guide/index.html b/docs/1.13/contributing-guide/index.html index 09bd0b1c67..0d5932a837 100644 --- a/docs/1.13/contributing-guide/index.html +++ b/docs/1.13/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 1.13

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 1.13

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/1.13/css-guidelines/index.html b/docs/1.13/css-guidelines/index.html index de0d1b72e9..99acc0d11a 100644 --- a/docs/1.13/css-guidelines/index.html +++ b/docs/1.13/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 1.13

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 1.13

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/1.13/discover/index.html b/docs/1.13/discover/index.html index bf59d77b27..38de333e85 100644 --- a/docs/1.13/discover/index.html +++ b/docs/1.13/discover/index.html @@ -2,13 +2,13 @@ - -Getting started with Richie | Richie - - + +Getting started with Richie | Richie + + -
    Version: 1.13

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    +
    Version: 1.13

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    Login/password are admin/admin. The database is regularly flushed.

    Architecture

    Richie is a container-native application but can also be installed @@ -48,6 +48,6 @@

    Adding conten

    Note that if you don't create the demo site and start from a blank CMS, you will get some errors requesting you to create some required root pages. So it is easier as a first approach to test the CMS with the demo site.

    -

    You should be able to view the site at localhost:8070

    +

    You should be able to view the site at localhost:8070

    \ No newline at end of file diff --git a/docs/1.13/django-react-interop/index.html b/docs/1.13/django-react-interop/index.html index 5366c78bd8..441c6392a1 100644 --- a/docs/1.13/django-react-interop/index.html +++ b/docs/1.13/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 1.13

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 1.13

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -57,6 +57,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/1.13/docker-development/index.html b/docs/1.13/docker-development/index.html index fd8b922e9e..2629dd58a2 100644 --- a/docs/1.13/docker-development/index.html +++ b/docs/1.13/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 1.13

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 1.13

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -75,6 +75,6 @@

    [1]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]

    In this case, increase virtual memory as follows (UNIX systems):

    -
    $ sudo sysctl -w vm/max_map_count=262144
    +
    $ sudo sysctl -w vm/max_map_count=262144
    \ No newline at end of file diff --git a/docs/1.13/native-installation/index.html b/docs/1.13/native-installation/index.html index e97cf771f0..4ab6fa6d98 100644 --- a/docs/1.13/native-installation/index.html +++ b/docs/1.13/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 1.13

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 1.13

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native instructions.

    @@ -108,6 +108,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/1.14/building-the-frontend/index.html b/docs/1.14/building-the-frontend/index.html index e5ca4e9fcd..769ffe8643 100644 --- a/docs/1.14/building-the-frontend/index.html +++ b/docs/1.14/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 1.14

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 1.14

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/1.14/contributing-guide/index.html b/docs/1.14/contributing-guide/index.html index 3e611ee23d..32b004016c 100644 --- a/docs/1.14/contributing-guide/index.html +++ b/docs/1.14/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 1.14

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 1.14

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/1.14/css-guidelines/index.html b/docs/1.14/css-guidelines/index.html index e7545236be..641e910614 100644 --- a/docs/1.14/css-guidelines/index.html +++ b/docs/1.14/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 1.14

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 1.14

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/1.14/discover/index.html b/docs/1.14/discover/index.html index 31ddfdb359..f3c6f566bc 100644 --- a/docs/1.14/discover/index.html +++ b/docs/1.14/discover/index.html @@ -2,13 +2,13 @@ - -Getting started with Richie | Richie - - + +Getting started with Richie | Richie + + -
    Version: 1.14

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    +
    Version: 1.14

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    Login/password are admin/admin. The database is regularly flushed.

    Architecture

    Richie is a container-native application but can also be installed @@ -48,6 +48,6 @@

    Adding conten

    Note that if you don't create the demo site and start from a blank CMS, you will get some errors requesting you to create some required root pages. So it is easier as a first approach to test the CMS with the demo site.

    -

    You should be able to view the site at localhost:8070

    +

    You should be able to view the site at localhost:8070

    \ No newline at end of file diff --git a/docs/1.14/django-react-interop/index.html b/docs/1.14/django-react-interop/index.html index b566bd1160..e4d23997cf 100644 --- a/docs/1.14/django-react-interop/index.html +++ b/docs/1.14/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 1.14

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 1.14

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -59,6 +59,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/1.14/docker-development/index.html b/docs/1.14/docker-development/index.html index 286fb2fb36..f30c1e9bd6 100644 --- a/docs/1.14/docker-development/index.html +++ b/docs/1.14/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 1.14

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 1.14

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -75,6 +75,6 @@

    [1]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]

    In this case, increase virtual memory as follows (UNIX systems):

    -
    $ sudo sysctl -w vm/max_map_count=262144
    +
    $ sudo sysctl -w vm/max_map_count=262144
    \ No newline at end of file diff --git a/docs/1.14/native-installation/index.html b/docs/1.14/native-installation/index.html index 38b655e1d8..6e29ecade8 100644 --- a/docs/1.14/native-installation/index.html +++ b/docs/1.14/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 1.14

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 1.14

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native instructions.

    @@ -108,6 +108,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/1.15/building-the-frontend/index.html b/docs/1.15/building-the-frontend/index.html index 9ed9b9eef4..668b4c2a15 100644 --- a/docs/1.15/building-the-frontend/index.html +++ b/docs/1.15/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 1.15

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 1.15

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/1.15/contributing-guide/index.html b/docs/1.15/contributing-guide/index.html index 86cd126534..b875ca0862 100644 --- a/docs/1.15/contributing-guide/index.html +++ b/docs/1.15/contributing-guide/index.html @@ -2,10 +2,10 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + +
    Version: 1.15

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/1.15/css-guidelines/index.html b/docs/1.15/css-guidelines/index.html index 1ee43128c4..6e49f1c9bb 100644 --- a/docs/1.15/css-guidelines/index.html +++ b/docs/1.15/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 1.15

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 1.15

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/1.15/discover/index.html b/docs/1.15/discover/index.html index a69b9516b5..8791a76415 100644 --- a/docs/1.15/discover/index.html +++ b/docs/1.15/discover/index.html @@ -2,13 +2,13 @@ - -Getting started with Richie | Richie - - + +Getting started with Richie | Richie + + -
    Version: 1.15

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    +
    Version: 1.15

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    Login/password are admin/admin. The database is regularly flushed.

    Architecture

    Richie is a container-native application but can also be installed @@ -48,6 +48,6 @@

    Adding conten

    Note that if you don't create the demo site and start from a blank CMS, you will get some errors requesting you to create some required root pages. So it is easier as a first approach to test the CMS with the demo site.

    -

    You should be able to view the site at localhost:8070

    +

    You should be able to view the site at localhost:8070

    \ No newline at end of file diff --git a/docs/1.15/django-react-interop/index.html b/docs/1.15/django-react-interop/index.html index cd839af79c..09cab7ac9f 100644 --- a/docs/1.15/django-react-interop/index.html +++ b/docs/1.15/django-react-interop/index.html @@ -2,10 +2,10 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/1.15/docker-development/index.html b/docs/1.15/docker-development/index.html index 41529920da..6caec22227 100644 --- a/docs/1.15/docker-development/index.html +++ b/docs/1.15/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 1.15

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 1.15

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -75,6 +75,6 @@

    [1]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]

    In this case, increase virtual memory as follows (UNIX systems):

    -
    $ sudo sysctl -w vm/max_map_count=262144
    +
    $ sudo sysctl -w vm/max_map_count=262144
    \ No newline at end of file diff --git a/docs/1.15/native-installation/index.html b/docs/1.15/native-installation/index.html index f988b6222f..e886253b87 100644 --- a/docs/1.15/native-installation/index.html +++ b/docs/1.15/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 1.15

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 1.15

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native instructions.

    @@ -108,6 +108,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/1.16/accessibility-testing/index.html b/docs/1.16/accessibility-testing/index.html index 7377ad8d73..1ff7cb6823 100644 --- a/docs/1.16/accessibility-testing/index.html +++ b/docs/1.16/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 1.16

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 1.16

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems in any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/1.16/building-the-frontend/index.html b/docs/1.16/building-the-frontend/index.html index 1c9ba63aa5..397e344ba5 100644 --- a/docs/1.16/building-the-frontend/index.html +++ b/docs/1.16/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 1.16

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 1.16

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/1.16/contributing-guide/index.html b/docs/1.16/contributing-guide/index.html index a1fad0d883..79dad54ef8 100644 --- a/docs/1.16/contributing-guide/index.html +++ b/docs/1.16/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 1.16

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 1.16

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/1.16/css-guidelines/index.html b/docs/1.16/css-guidelines/index.html index 7b10b276a4..e08d338295 100644 --- a/docs/1.16/css-guidelines/index.html +++ b/docs/1.16/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 1.16

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 1.16

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/1.16/discover/index.html b/docs/1.16/discover/index.html index bc58d2ad80..be6e993013 100644 --- a/docs/1.16/discover/index.html +++ b/docs/1.16/discover/index.html @@ -2,13 +2,13 @@ - -Getting started with Richie | Richie - - + +Getting started with Richie | Richie + + -
    Version: 1.16

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    +
    Version: 1.16

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    Login/password are admin/admin. The database is regularly flushed.

    Architecture

    Richie is a container-native application but can also be installed @@ -48,6 +48,6 @@

    Adding conten

    Note that if you don't create the demo site and start from a blank CMS, you will get some errors requesting you to create some required root pages. So it is easier as a first approach to test the CMS with the demo site.

    -

    You should be able to view the site at localhost:8070

    +

    You should be able to view the site at localhost:8070

    \ No newline at end of file diff --git a/docs/1.16/django-react-interop/index.html b/docs/1.16/django-react-interop/index.html index 7b2d499d9f..93660c91f3 100644 --- a/docs/1.16/django-react-interop/index.html +++ b/docs/1.16/django-react-interop/index.html @@ -2,10 +2,10 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/1.16/docker-development/index.html b/docs/1.16/docker-development/index.html index d3127b6de7..3fe76cd1c3 100644 --- a/docs/1.16/docker-development/index.html +++ b/docs/1.16/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 1.16

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 1.16

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -75,6 +75,6 @@

    [1]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]

    In this case, increase virtual memory as follows (UNIX systems):

    -
    $ sudo sysctl -w vm/max_map_count=262144
    +
    $ sudo sysctl -w vm/max_map_count=262144
    \ No newline at end of file diff --git a/docs/1.16/native-installation/index.html b/docs/1.16/native-installation/index.html index 8ea46bf922..2f4b1e861b 100644 --- a/docs/1.16/native-installation/index.html +++ b/docs/1.16/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 1.16

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 1.16

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native instructions.

    @@ -108,6 +108,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/1.17/accessibility-testing/index.html b/docs/1.17/accessibility-testing/index.html index ddc04a4f08..a63f3a9aef 100644 --- a/docs/1.17/accessibility-testing/index.html +++ b/docs/1.17/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 1.17

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 1.17

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems in any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/1.17/building-the-frontend/index.html b/docs/1.17/building-the-frontend/index.html index d46682f5a9..fb2696ccd0 100644 --- a/docs/1.17/building-the-frontend/index.html +++ b/docs/1.17/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 1.17

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 1.17

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/1.17/contributing-guide/index.html b/docs/1.17/contributing-guide/index.html index 376ac4c62b..c2829c32fd 100644 --- a/docs/1.17/contributing-guide/index.html +++ b/docs/1.17/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 1.17

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 1.17

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/1.17/css-guidelines/index.html b/docs/1.17/css-guidelines/index.html index 97d985033b..62e30b98df 100644 --- a/docs/1.17/css-guidelines/index.html +++ b/docs/1.17/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 1.17

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 1.17

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/1.17/discover/index.html b/docs/1.17/discover/index.html index b07b9f335e..95aa867503 100644 --- a/docs/1.17/discover/index.html +++ b/docs/1.17/discover/index.html @@ -2,13 +2,13 @@ - -Getting started with Richie | Richie - - + +Getting started with Richie | Richie + + -
    Version: 1.17

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    +
    Version: 1.17

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    Login/password are admin/admin. The database is regularly flushed.

    Architecture

    Richie is a container-native application but can also be installed @@ -48,6 +48,6 @@

    Adding conten

    Note that if you don't create the demo site and start from a blank CMS, you will get some errors requesting you to create some required root pages. So it is easier as a first approach to test the CMS with the demo site.

    -

    You should be able to view the site at localhost:8070

    +

    You should be able to view the site at localhost:8070

    \ No newline at end of file diff --git a/docs/1.17/django-react-interop/index.html b/docs/1.17/django-react-interop/index.html index a19f12cbdd..1882ea2c83 100644 --- a/docs/1.17/django-react-interop/index.html +++ b/docs/1.17/django-react-interop/index.html @@ -2,10 +2,10 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/1.17/docker-development/index.html b/docs/1.17/docker-development/index.html index f4b6c95182..50464f0954 100644 --- a/docs/1.17/docker-development/index.html +++ b/docs/1.17/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 1.17

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 1.17

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -75,6 +75,6 @@

    [1]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]

    In this case, increase virtual memory as follows (UNIX systems):

    -
    $ sudo sysctl -w vm/max_map_count=262144
    +
    $ sudo sysctl -w vm/max_map_count=262144
    \ No newline at end of file diff --git a/docs/1.17/native-installation/index.html b/docs/1.17/native-installation/index.html index 64b5cec5e1..99e50ebdc4 100644 --- a/docs/1.17/native-installation/index.html +++ b/docs/1.17/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 1.17

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 1.17

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native instructions.

    @@ -108,6 +108,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.0.0/accessibility-testing/index.html b/docs/2.0.0/accessibility-testing/index.html index 811d3c86aa..0978f4e422 100644 --- a/docs/2.0.0/accessibility-testing/index.html +++ b/docs/2.0.0/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.0.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.0.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems in any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.0.0/building-the-frontend/index.html b/docs/2.0.0/building-the-frontend/index.html index a3bceff22f..31a6a234e1 100644 --- a/docs/2.0.0/building-the-frontend/index.html +++ b/docs/2.0.0/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.0.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.0.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.0.0/contributing-guide/index.html b/docs/2.0.0/contributing-guide/index.html index 4797859edd..34ab127e0d 100644 --- a/docs/2.0.0/contributing-guide/index.html +++ b/docs/2.0.0/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.0.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.0.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.0.0/css-guidelines/index.html b/docs/2.0.0/css-guidelines/index.html index e1154d69cf..7e94c2c27c 100644 --- a/docs/2.0.0/css-guidelines/index.html +++ b/docs/2.0.0/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.0.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.0.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.0.0/discover/index.html b/docs/2.0.0/discover/index.html index 9591884693..5eae3a6b97 100644 --- a/docs/2.0.0/discover/index.html +++ b/docs/2.0.0/discover/index.html @@ -2,13 +2,13 @@ - -Getting started with Richie | Richie - - + +Getting started with Richie | Richie + + -
    Version: 2.0.0

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    +
    Version: 2.0.0

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    Login/password are admin/admin. The database is regularly flushed.

    Architecture

    Richie is a container-native application but can also be installed @@ -60,6 +60,6 @@

    Advanced - Connecting Richie to OpenEdx

    If you want users to enroll on courses in OpenEdx directly from Richie via API calls, you should read the advanced guide to connect -Richie to OpenEdx over TLS.

    +Richie to OpenEdx over TLS.

    \ No newline at end of file diff --git a/docs/2.0.0/django-react-interop/index.html b/docs/2.0.0/django-react-interop/index.html index 3f1c72444d..55e2e623a9 100644 --- a/docs/2.0.0/django-react-interop/index.html +++ b/docs/2.0.0/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.0.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.0.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -65,6 +65,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.0.0/docker-development/index.html b/docs/2.0.0/docker-development/index.html index ef42d3479c..999a11b884 100644 --- a/docs/2.0.0/docker-development/index.html +++ b/docs/2.0.0/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.0.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.0.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.0.0/frontend-overrides/index.html b/docs/2.0.0/frontend-overrides/index.html index f9fe8f7e1b..9c2e1e0a40 100644 --- a/docs/2.0.0/frontend-overrides/index.html +++ b/docs/2.0.0/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.0.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.0.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.0.0/lms-connection/index.html b/docs/2.0.0/lms-connection/index.html index 741e4628c3..ed7346bf0d 100644 --- a/docs/2.0.0/lms-connection/index.html +++ b/docs/2.0.0/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with an LMS | Richie - - + +Connecting Richie with an LMS | Richie + + -
    Version: 2.0.0

    Connecting Richie with an LMS

    richie can be connected to one or more Learning Management Systems (LMS) like OpenEdx, Moodle +

    Version: 2.0.0

    Connecting Richie with an LMS

    richie can be connected to one or more Learning Management Systems (LMS) like OpenEdx, Moodle or Canvas for a seamless experience between browsing the course catalog on richie and following the course itself on the LMS.

    In order to connect richie with a LMS, there is an API bridge @@ -81,6 +81,6 @@

    https://richie.local.dev:8070 without browser warning about the certificate validity.

    You need to follow these steps once. If you want to use SSL later, just use make run-ssl to run OpenEdx and Richie apps. -Of course, you can still run apps without ssl by using make run.

    +Of course, you can still run apps without ssl by using make run.

    \ No newline at end of file diff --git a/docs/2.0.0/native-installation/index.html b/docs/2.0.0/native-installation/index.html index 9ab5ee9989..7671e0ac66 100644 --- a/docs/2.0.0/native-installation/index.html +++ b/docs/2.0.0/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.0.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.0.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.0.1/accessibility-testing/index.html b/docs/2.0.1/accessibility-testing/index.html index 3c32a978ff..702908fa23 100644 --- a/docs/2.0.1/accessibility-testing/index.html +++ b/docs/2.0.1/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.0.1

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.0.1

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems in any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.0.1/building-the-frontend/index.html b/docs/2.0.1/building-the-frontend/index.html index 76a5fedf16..180ffa860c 100644 --- a/docs/2.0.1/building-the-frontend/index.html +++ b/docs/2.0.1/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.0.1

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.0.1

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.0.1/contributing-guide/index.html b/docs/2.0.1/contributing-guide/index.html index f05eacf204..b1e551e741 100644 --- a/docs/2.0.1/contributing-guide/index.html +++ b/docs/2.0.1/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.0.1

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.0.1

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.0.1/css-guidelines/index.html b/docs/2.0.1/css-guidelines/index.html index d261e54bdb..57d4817306 100644 --- a/docs/2.0.1/css-guidelines/index.html +++ b/docs/2.0.1/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.0.1

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.0.1

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.0.1/discover/index.html b/docs/2.0.1/discover/index.html index 46972b6e2a..1ca748b1ff 100644 --- a/docs/2.0.1/discover/index.html +++ b/docs/2.0.1/discover/index.html @@ -2,13 +2,13 @@ - -Getting started with Richie | Richie - - + +Getting started with Richie | Richie + + -
    Version: 2.0.1

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    +
    Version: 2.0.1

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    Login/password are admin/admin. The database is regularly flushed.

    Architecture

    Richie is a container-native application but can also be installed @@ -60,6 +60,6 @@

    Advanced - Connecting Richie to OpenEdx

    If you want users to enroll on courses in OpenEdx directly from Richie via API calls, you should read the advanced guide to connect -Richie to OpenEdx over TLS.

    +Richie to OpenEdx over TLS.

    \ No newline at end of file diff --git a/docs/2.0.1/django-react-interop/index.html b/docs/2.0.1/django-react-interop/index.html index 13f8c66b8c..b9b96d49a0 100644 --- a/docs/2.0.1/django-react-interop/index.html +++ b/docs/2.0.1/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.0.1

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.0.1

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -65,6 +65,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.0.1/docker-development/index.html b/docs/2.0.1/docker-development/index.html index edac63d6e1..824c3e6612 100644 --- a/docs/2.0.1/docker-development/index.html +++ b/docs/2.0.1/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.0.1

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.0.1

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.0.1/frontend-overrides/index.html b/docs/2.0.1/frontend-overrides/index.html index 0e97541200..dbec372016 100644 --- a/docs/2.0.1/frontend-overrides/index.html +++ b/docs/2.0.1/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.0.1

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.0.1

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.0.1/lms-connection/index.html b/docs/2.0.1/lms-connection/index.html index 0b9b326109..98b6028c47 100644 --- a/docs/2.0.1/lms-connection/index.html +++ b/docs/2.0.1/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with an LMS | Richie - - + +Connecting Richie with an LMS | Richie + + -
    Version: 2.0.1

    Connecting Richie with an LMS

    richie can be connected to one or more Learning Management Systems (LMS) like OpenEdx, Moodle +

    Version: 2.0.1

    Connecting Richie with an LMS

    richie can be connected to one or more Learning Management Systems (LMS) like OpenEdx, Moodle or Canvas for a seamless experience between browsing the course catalog on richie and following the course itself on the LMS.

    In order to connect richie with a LMS, there is an API bridge @@ -81,6 +81,6 @@

    https://richie.local.dev:8070 without browser warning about the certificate validity.

    You need to follow these steps once. If you want to use SSL later, just use make run-ssl to run OpenEdx and Richie apps. -Of course, you can still run apps without ssl by using make run.

    +Of course, you can still run apps without ssl by using make run.

    \ No newline at end of file diff --git a/docs/2.0.1/native-installation/index.html b/docs/2.0.1/native-installation/index.html index 47e0375b90..f668258958 100644 --- a/docs/2.0.1/native-installation/index.html +++ b/docs/2.0.1/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.0.1

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.0.1

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.1.0/accessibility-testing/index.html b/docs/2.1.0/accessibility-testing/index.html index d9a2c7390b..970f937b53 100644 --- a/docs/2.1.0/accessibility-testing/index.html +++ b/docs/2.1.0/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.1.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.1.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems in any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.1.0/building-the-frontend/index.html b/docs/2.1.0/building-the-frontend/index.html index e56b6ddfc9..102aa42326 100644 --- a/docs/2.1.0/building-the-frontend/index.html +++ b/docs/2.1.0/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.1.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.1.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.1.0/contributing-guide/index.html b/docs/2.1.0/contributing-guide/index.html index 9b23ab67cf..4120b151f2 100644 --- a/docs/2.1.0/contributing-guide/index.html +++ b/docs/2.1.0/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.1.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.1.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.1.0/css-guidelines/index.html b/docs/2.1.0/css-guidelines/index.html index 6936d8b29c..d29ed76901 100644 --- a/docs/2.1.0/css-guidelines/index.html +++ b/docs/2.1.0/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.1.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.1.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.1.0/discover/index.html b/docs/2.1.0/discover/index.html index 5972fdff59..7e102d5362 100644 --- a/docs/2.1.0/discover/index.html +++ b/docs/2.1.0/discover/index.html @@ -2,13 +2,13 @@ - -Getting started with Richie | Richie - - + +Getting started with Richie | Richie + + -
    Version: 2.1.0

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    +
    Version: 2.1.0

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    Login/password are admin/admin. The database is regularly flushed.

    Architecture

    Richie is a container-native application but can also be installed @@ -60,6 +60,6 @@

    Advanced - Connecting Richie to OpenEdx

    If you want users to enroll on courses in OpenEdx directly from Richie via API calls, you should read the advanced guide to connect -Richie to OpenEdx over TLS.

    +Richie to OpenEdx over TLS.

    \ No newline at end of file diff --git a/docs/2.1.0/django-react-interop/index.html b/docs/2.1.0/django-react-interop/index.html index 68f6c1ff00..8ed20ef94d 100644 --- a/docs/2.1.0/django-react-interop/index.html +++ b/docs/2.1.0/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.1.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.1.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -65,6 +65,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.1.0/docker-development/index.html b/docs/2.1.0/docker-development/index.html index 8455f0a45d..628fbb02c7 100644 --- a/docs/2.1.0/docker-development/index.html +++ b/docs/2.1.0/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.1.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.1.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.1.0/frontend-overrides/index.html b/docs/2.1.0/frontend-overrides/index.html index 9d47da3189..71bd3c823e 100644 --- a/docs/2.1.0/frontend-overrides/index.html +++ b/docs/2.1.0/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.1.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.1.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.1.0/lms-connection/index.html b/docs/2.1.0/lms-connection/index.html index e5c2e230b3..b3106937c4 100644 --- a/docs/2.1.0/lms-connection/index.html +++ b/docs/2.1.0/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with an LMS | Richie - - + +Connecting Richie with an LMS | Richie + + -
    Version: 2.1.0

    Connecting Richie with an LMS

    richie can be connected to one or more Learning Management Systems (LMS) like OpenEdx, Moodle +

    Version: 2.1.0

    Connecting Richie with an LMS

    richie can be connected to one or more Learning Management Systems (LMS) like OpenEdx, Moodle or Canvas for a seamless experience between browsing the course catalog on richie and following the course itself on the LMS.

    In order to connect richie with a LMS, there is an API bridge @@ -81,6 +81,6 @@

    https://richie.local.dev:8070 without browser warning about the certificate validity.

    You need to follow these steps once. If you want to use SSL later, just use make run-ssl to run OpenEdx and Richie apps. -Of course, you can still run apps without ssl by using make run.

    +Of course, you can still run apps without ssl by using make run.

    \ No newline at end of file diff --git a/docs/2.1.0/native-installation/index.html b/docs/2.1.0/native-installation/index.html index 8d8531ff64..cf01427007 100644 --- a/docs/2.1.0/native-installation/index.html +++ b/docs/2.1.0/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.1.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.1.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.10.0/accessibility-testing/index.html b/docs/2.10.0/accessibility-testing/index.html index 373a89b403..71d1844401 100644 --- a/docs/2.10.0/accessibility-testing/index.html +++ b/docs/2.10.0/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.10.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.10.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems in any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.10.0/api/course-run-synchronization-api/index.html b/docs/2.10.0/api/course-run-synchronization-api/index.html index b77f4ca479..1d670123e2 100644 --- a/docs/2.10.0/api/course-run-synchronization-api/index.html +++ b/docs/2.10.0/api/course-run-synchronization-api/index.html @@ -2,10 +2,10 @@ - -Course run synchronization API | Richie - - + +Course run synchronization API | Richie + +
    Version: 2.10.0

    Course run synchronization API

    API endpoint allowing remote systems to synchronize their course runs with a Richie instance.

    @@ -52,6 +52,6 @@

    +
    \ No newline at end of file diff --git a/docs/2.10.0/building-the-frontend/index.html b/docs/2.10.0/building-the-frontend/index.html index d83cf0d274..2e8d40adba 100644 --- a/docs/2.10.0/building-the-frontend/index.html +++ b/docs/2.10.0/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.10.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.10.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.10.0/contributing-guide/index.html b/docs/2.10.0/contributing-guide/index.html index 471a9f7380..d5ba92d133 100644 --- a/docs/2.10.0/contributing-guide/index.html +++ b/docs/2.10.0/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.10.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.10.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.10.0/css-guidelines/index.html b/docs/2.10.0/css-guidelines/index.html index 011f8d5988..d1016fb904 100644 --- a/docs/2.10.0/css-guidelines/index.html +++ b/docs/2.10.0/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.10.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.10.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.10.0/discover/index.html b/docs/2.10.0/discover/index.html index 7b7c6b74c6..5ca77a29e7 100644 --- a/docs/2.10.0/discover/index.html +++ b/docs/2.10.0/discover/index.html @@ -2,13 +2,13 @@ - -Getting started with Richie | Richie - - + +Getting started with Richie | Richie + + -
    Version: 2.10.0

    Getting started with Richie

    If you're looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    +
    Version: 2.10.0

    Getting started with Richie

    If you're looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    Login/password are admin/admin. The database is regularly flushed.

    Architecture

    Richie is a container-native application but can also be installed @@ -55,6 +55,6 @@

    This approach is used for example on https://www.fun-campus.fr or https://catalogue.edulib.org.

    For a seamless user experience, it is possible to connect a Richie instance to an OpenEdX instance (or some other LMS like Moodle at the cost of minor adaptations), in several ways that we explain in -the LMS connection guide.

    +the LMS connection guide.

    \ No newline at end of file diff --git a/docs/2.10.0/displaying-connection-status/index.html b/docs/2.10.0/displaying-connection-status/index.html index 11814fbbb3..df0ae72aee 100644 --- a/docs/2.10.0/displaying-connection-status/index.html +++ b/docs/2.10.0/displaying-connection-status/index.html @@ -2,10 +2,10 @@ - -Displaying OpenEdX connection status in Richie | Richie - - + +Displaying OpenEdX connection status in Richie | Richie + + +
    \ No newline at end of file diff --git a/docs/2.10.0/django-react-interop/index.html b/docs/2.10.0/django-react-interop/index.html index db7e6c1a53..eaeb654a00 100644 --- a/docs/2.10.0/django-react-interop/index.html +++ b/docs/2.10.0/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.10.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.10.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -64,6 +64,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.10.0/docker-development/index.html b/docs/2.10.0/docker-development/index.html index 3c028ee252..05f9a45416 100644 --- a/docs/2.10.0/docker-development/index.html +++ b/docs/2.10.0/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.10.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.10.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.10.0/frontend-overrides/index.html b/docs/2.10.0/frontend-overrides/index.html index d4c4c16d72..c5ea70f3d8 100644 --- a/docs/2.10.0/frontend-overrides/index.html +++ b/docs/2.10.0/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.10.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.10.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.10.0/internationalization/index.html b/docs/2.10.0/internationalization/index.html index 9d3f579668..75f3e8ded5 100644 --- a/docs/2.10.0/internationalization/index.html +++ b/docs/2.10.0/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.10.0

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.10.0

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.10.0/lms-backends/index.html b/docs/2.10.0/lms-backends/index.html index 431c1e58f2..2a36a71bdc 100644 --- a/docs/2.10.0/lms-backends/index.html +++ b/docs/2.10.0/lms-backends/index.html @@ -2,10 +2,10 @@ - -Configuring LMS Backends | Richie - - + +Configuring LMS Backends | Richie + +
    Version: 2.10.0

    Configuring LMS Backends

    Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless @@ -115,6 +115,6 @@

    Technical

    If you encounter an issue with this documentation or the backends included in Richie, please open an issue on our repository.

    If you need a custom backend, you can submit a PR or -open an issue and we will consider adding it.

    +open an issue and we will consider adding it.

    \ No newline at end of file diff --git a/docs/2.10.0/lms-connection/index.html b/docs/2.10.0/lms-connection/index.html index a3ce478352..3223ecd674 100644 --- a/docs/2.10.0/lms-connection/index.html +++ b/docs/2.10.0/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with one or more LMS | Richie - - + +Connecting Richie with one or more LMS | Richie + + -
    Version: 2.10.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    +
    Version: 2.10.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    Richie can be connected to an LMS in several ways, ranging from SSO to a fully integrated seamless experience.

    As of today, each approach has been implemented for OpenEdX but the same could be done for @@ -63,6 +63,6 @@

    Development

    If you want to activate seamless enrollment locally for development, you will need to set up TLS domains for both Richie and OpenEdX. To do this, head over to our -guide on setting-up TLS connections for Richie and OpenEdX.

    +guide on setting-up TLS connections for Richie and OpenEdX.

    \ No newline at end of file diff --git a/docs/2.10.0/native-installation/index.html b/docs/2.10.0/native-installation/index.html index b40eaf57cb..960cc457d8 100644 --- a/docs/2.10.0/native-installation/index.html +++ b/docs/2.10.0/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.10.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.10.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.10.0/synchronizing-course-runs/index.html b/docs/2.10.0/synchronizing-course-runs/index.html index f033edebd3..1192049482 100644 --- a/docs/2.10.0/synchronizing-course-runs/index.html +++ b/docs/2.10.0/synchronizing-course-runs/index.html @@ -2,10 +2,10 @@ - -Synchronizing course runs between Richie and OpenEdX | Richie - - + +Synchronizing course runs between Richie and OpenEdX | Richie + +
    Version: 2.10.0

    Synchronizing course runs between Richie and OpenEdX

    Richie can receive automatic course runs updates on a dedicated API endpoint.

    @@ -51,6 +51,6 @@

    import hashlib
    import hmac
    import json

    from django.conf import settings

    from microsite_configuration import microsite
    import requests
    from xmodule.modulestore.django import modulestore


    def update_course(course_key, *args, **kwargs):
    """Synchronize an OpenEdX course, identified by its course key, with a Richie instance."""
    course = modulestore().get_course(course_key)
    edxapp_domain = microsite.get_value("site_domain", settings.LMS_BASE)

    data = {
    "resource_link": "https://{:s}/courses/{!s}/info".format(
    edxapp_domain, course_key
    ),
    "start": course.start and course.start.isoformat(),
    "end": course.end and course.end.isoformat(),
    "enrollment_start": course.enrollment_start and course.enrollment_start.isoformat(),
    "enrollment_end": course.enrollment_end and course.enrollment_end.isoformat(),
    "languages": [course.language or settings.LANGUAGE_CODE],
    }

    signature = hmac.new(
    setting.COURSE_HOOK["secret"].encode("utf-8"),
    msg=json.dumps(data).encode("utf-8"),
    digestmod=hashlib.sha256,
    ).hexdigest()

    response = requests.post(
    setting.COURSE_HOOK["url"],
    json=data,
    headers={"Authorization": "SIG-HMAC-SHA256 {:s}".format(signature)},
    )

    Thanks to the signal emitted in OpenEdX, this function can then be triggered each time a course is modified and published:

    -
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    +
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    \ No newline at end of file diff --git a/docs/2.10.0/tls-connection/index.html b/docs/2.10.0/tls-connection/index.html index 249cb6542f..95d83f3571 100644 --- a/docs/2.10.0/tls-connection/index.html +++ b/docs/2.10.0/tls-connection/index.html @@ -2,10 +2,10 @@ - -Connecting Richie and OpenEdX over TLS for development | Richie - - + +Connecting Richie and OpenEdX over TLS for development | Richie + +
    Version: 2.10.0

    Connecting Richie and OpenEdX over TLS for development

    Purpose

    @@ -68,6 +68,6 @@

    $ make run-ssl

    Of course, you can still run apps without ssl by using:

    -
    $ make run
    +
    $ make run
    \ No newline at end of file diff --git a/docs/2.10.0/web-analytics/index.html b/docs/2.10.0/web-analytics/index.html index bacbe75dba..ef40ed7358 100644 --- a/docs/2.10.0/web-analytics/index.html +++ b/docs/2.10.0/web-analytics/index.html @@ -2,13 +2,13 @@ - -Add web analytics to your site | Richie - - + +Add web analytics to your site | Richie + + -
    Version: 2.10.0

    Add web analytics to your site

    The purpose of this file is to document how you can enable a Web Analytics solution. +

    Version: 2.10.0

    Add web analytics to your site

    The purpose of this file is to document how you can enable a Web Analytics solution. Currently Richie only supports by default the Google Analytics using the Google Tag Manager Javascript. But it is possible with little cost to add support for other web analytics solutions.

    Google Analytics

    @@ -53,6 +53,6 @@

    <script type="text/javascript">
    console.log("organization codes: '{{ WEB_ANALYTICS.DIMENSIONS.organizations_codes |join:" | " }}");
    </script>

    +
    <script type="text/javascript">
    console.log("organization codes: '{{ WEB_ANALYTICS.DIMENSIONS.organizations_codes |join:" | " }}");
    </script>
    \ No newline at end of file diff --git a/docs/2.11.0/accessibility-testing/index.html b/docs/2.11.0/accessibility-testing/index.html index 0ffc41a2a5..6f274c2441 100644 --- a/docs/2.11.0/accessibility-testing/index.html +++ b/docs/2.11.0/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.11.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.11.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems in any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.11.0/api/course-run-synchronization-api/index.html b/docs/2.11.0/api/course-run-synchronization-api/index.html index 91a9d44289..b3df54382c 100644 --- a/docs/2.11.0/api/course-run-synchronization-api/index.html +++ b/docs/2.11.0/api/course-run-synchronization-api/index.html @@ -2,10 +2,10 @@ - -Course run synchronization API | Richie - - + +Course run synchronization API | Richie + +
    Version: 2.11.0

    Course run synchronization API

    API endpoint allowing remote systems to synchronize their course runs with a Richie instance.

    @@ -52,6 +52,6 @@

    +
    \ No newline at end of file diff --git a/docs/2.11.0/building-the-frontend/index.html b/docs/2.11.0/building-the-frontend/index.html index 8468387eba..e20335c4f0 100644 --- a/docs/2.11.0/building-the-frontend/index.html +++ b/docs/2.11.0/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.11.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.11.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.11.0/contributing-guide/index.html b/docs/2.11.0/contributing-guide/index.html index 2413ce67f7..14d6943851 100644 --- a/docs/2.11.0/contributing-guide/index.html +++ b/docs/2.11.0/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.11.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.11.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.11.0/css-guidelines/index.html b/docs/2.11.0/css-guidelines/index.html index f1983512f0..8f9f340c7a 100644 --- a/docs/2.11.0/css-guidelines/index.html +++ b/docs/2.11.0/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.11.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.11.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.11.0/discover/index.html b/docs/2.11.0/discover/index.html index e9ce7ab8a0..c1a45d8c9a 100644 --- a/docs/2.11.0/discover/index.html +++ b/docs/2.11.0/discover/index.html @@ -2,13 +2,13 @@ - -Getting started with Richie | Richie - - + +Getting started with Richie | Richie + + -
    Version: 2.11.0

    Getting started with Richie

    If you're looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    +
    Version: 2.11.0

    Getting started with Richie

    If you're looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    Login/password are admin/admin. The database is regularly flushed.

    Architecture

    Richie is a container-native application but can also be installed @@ -55,6 +55,6 @@

    This approach is used for example on https://www.fun-campus.fr or https://catalogue.edulib.org.

    For a seamless user experience, it is possible to connect a Richie instance to an OpenEdX instance (or some other LMS like Moodle at the cost of minor adaptations), in several ways that we explain in -the LMS connection guide.

    +the LMS connection guide.

    \ No newline at end of file diff --git a/docs/2.11.0/displaying-connection-status/index.html b/docs/2.11.0/displaying-connection-status/index.html index 62a3337dcc..556fed920e 100644 --- a/docs/2.11.0/displaying-connection-status/index.html +++ b/docs/2.11.0/displaying-connection-status/index.html @@ -2,10 +2,10 @@ - -Displaying OpenEdX connection status in Richie | Richie - - + +Displaying OpenEdX connection status in Richie | Richie + + +
    \ No newline at end of file diff --git a/docs/2.11.0/django-react-interop/index.html b/docs/2.11.0/django-react-interop/index.html index 7bc901d631..6ba4292ade 100644 --- a/docs/2.11.0/django-react-interop/index.html +++ b/docs/2.11.0/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.11.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.11.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -64,6 +64,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.11.0/docker-development/index.html b/docs/2.11.0/docker-development/index.html index 423e73510e..8f0cb5877b 100644 --- a/docs/2.11.0/docker-development/index.html +++ b/docs/2.11.0/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.11.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.11.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.11.0/frontend-overrides/index.html b/docs/2.11.0/frontend-overrides/index.html index 33a50e3968..d4c5d4b298 100644 --- a/docs/2.11.0/frontend-overrides/index.html +++ b/docs/2.11.0/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.11.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.11.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.11.0/internationalization/index.html b/docs/2.11.0/internationalization/index.html index 0a98d51400..4443f79c64 100644 --- a/docs/2.11.0/internationalization/index.html +++ b/docs/2.11.0/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.11.0

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.11.0

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.11.0/lms-backends/index.html b/docs/2.11.0/lms-backends/index.html index 6d1bc63866..bf72eca73e 100644 --- a/docs/2.11.0/lms-backends/index.html +++ b/docs/2.11.0/lms-backends/index.html @@ -2,10 +2,10 @@ - -Configuring LMS Backends | Richie - - + +Configuring LMS Backends | Richie + +
    Version: 2.11.0

    Configuring LMS Backends

    Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless @@ -115,6 +115,6 @@

    Technical

    If you encounter an issue with this documentation or the backends included in Richie, please open an issue on our repository.

    If you need a custom backend, you can submit a PR or -open an issue and we will consider adding it.

    +open an issue and we will consider adding it.

    \ No newline at end of file diff --git a/docs/2.11.0/lms-connection/index.html b/docs/2.11.0/lms-connection/index.html index 3d7e1ab30e..5be32b35a6 100644 --- a/docs/2.11.0/lms-connection/index.html +++ b/docs/2.11.0/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with one or more LMS | Richie - - + +Connecting Richie with one or more LMS | Richie + + -
    Version: 2.11.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    +
    Version: 2.11.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    Richie can be connected to an LMS in several ways, ranging from SSO to a fully integrated seamless experience.

    As of today, each approach has been implemented for OpenEdX but the same could be done for @@ -63,6 +63,6 @@

    Development

    If you want to activate seamless enrollment locally for development, you will need to set up TLS domains for both Richie and OpenEdX. To do this, head over to our -guide on setting-up TLS connections for Richie and OpenEdX.

    +guide on setting-up TLS connections for Richie and OpenEdX.

    \ No newline at end of file diff --git a/docs/2.11.0/native-installation/index.html b/docs/2.11.0/native-installation/index.html index 9a15bdbe9b..ec2bfa4ec2 100644 --- a/docs/2.11.0/native-installation/index.html +++ b/docs/2.11.0/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.11.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.11.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.11.0/synchronizing-course-runs/index.html b/docs/2.11.0/synchronizing-course-runs/index.html index 641d71ec05..ed53eb5bc7 100644 --- a/docs/2.11.0/synchronizing-course-runs/index.html +++ b/docs/2.11.0/synchronizing-course-runs/index.html @@ -2,10 +2,10 @@ - -Synchronizing course runs between Richie and OpenEdX | Richie - - + +Synchronizing course runs between Richie and OpenEdX | Richie + +
    Version: 2.11.0

    Synchronizing course runs between Richie and OpenEdX

    Richie can receive automatic course runs updates on a dedicated API endpoint.

    @@ -51,6 +51,6 @@

    import hashlib
    import hmac
    import json

    from django.conf import settings

    from microsite_configuration import microsite
    import requests
    from xmodule.modulestore.django import modulestore


    def update_course(course_key, *args, **kwargs):
    """Synchronize an OpenEdX course, identified by its course key, with a Richie instance."""
    course = modulestore().get_course(course_key)
    edxapp_domain = microsite.get_value("site_domain", settings.LMS_BASE)

    data = {
    "resource_link": "https://{:s}/courses/{!s}/info".format(
    edxapp_domain, course_key
    ),
    "start": course.start and course.start.isoformat(),
    "end": course.end and course.end.isoformat(),
    "enrollment_start": course.enrollment_start and course.enrollment_start.isoformat(),
    "enrollment_end": course.enrollment_end and course.enrollment_end.isoformat(),
    "languages": [course.language or settings.LANGUAGE_CODE],
    }

    signature = hmac.new(
    setting.COURSE_HOOK["secret"].encode("utf-8"),
    msg=json.dumps(data).encode("utf-8"),
    digestmod=hashlib.sha256,
    ).hexdigest()

    response = requests.post(
    setting.COURSE_HOOK["url"],
    json=data,
    headers={"Authorization": "SIG-HMAC-SHA256 {:s}".format(signature)},
    )

    Thanks to the signal emitted in OpenEdX, this function can then be triggered each time a course is modified and published:

    -
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    +
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    \ No newline at end of file diff --git a/docs/2.11.0/tls-connection/index.html b/docs/2.11.0/tls-connection/index.html index 7c625f4878..ff38b694f0 100644 --- a/docs/2.11.0/tls-connection/index.html +++ b/docs/2.11.0/tls-connection/index.html @@ -2,10 +2,10 @@ - -Connecting Richie and OpenEdX over TLS for development | Richie - - + +Connecting Richie and OpenEdX over TLS for development | Richie + +
    Version: 2.11.0

    Connecting Richie and OpenEdX over TLS for development

    Purpose

    @@ -68,6 +68,6 @@

    $ make run-ssl

    Of course, you can still run apps without ssl by using:

    -
    $ make run
    +
    $ make run
    \ No newline at end of file diff --git a/docs/2.11.0/web-analytics/index.html b/docs/2.11.0/web-analytics/index.html index 2c88f09507..bd863959b5 100644 --- a/docs/2.11.0/web-analytics/index.html +++ b/docs/2.11.0/web-analytics/index.html @@ -2,13 +2,13 @@ - -Add web analytics to your site | Richie - - + +Add web analytics to your site | Richie + + -
    Version: 2.11.0

    Add web analytics to your site

    The purpose of this file is to document how you can enable a Web Analytics solution. +

    Version: 2.11.0

    Add web analytics to your site

    The purpose of this file is to document how you can enable a Web Analytics solution. Currently Richie only supports by default the Google Analytics using the Google Tag Manager Javascript. But it is possible with little cost to add support for other web analytics solutions.

    Google Analytics

    @@ -53,6 +53,6 @@

    <script type="text/javascript">
    console.log("organization codes: '{{ WEB_ANALYTICS.DIMENSIONS.organizations_codes |join:" | " }}");
    </script>

    +
    <script type="text/javascript">
    console.log("organization codes: '{{ WEB_ANALYTICS.DIMENSIONS.organizations_codes |join:" | " }}");
    </script>
    \ No newline at end of file diff --git a/docs/2.12.0/accessibility-testing/index.html b/docs/2.12.0/accessibility-testing/index.html index a6e948e9f7..3a689878d6 100644 --- a/docs/2.12.0/accessibility-testing/index.html +++ b/docs/2.12.0/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.12.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.12.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems in any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.12.0/api/course-run-synchronization-api/index.html b/docs/2.12.0/api/course-run-synchronization-api/index.html index 175eb881ab..c9c83669df 100644 --- a/docs/2.12.0/api/course-run-synchronization-api/index.html +++ b/docs/2.12.0/api/course-run-synchronization-api/index.html @@ -2,10 +2,10 @@ - -Course run synchronization API | Richie - - + +Course run synchronization API | Richie + +
    Version: 2.12.0

    Course run synchronization API

    API endpoint allowing remote systems to synchronize their course runs with a Richie instance.

    @@ -52,6 +52,6 @@

    +
    \ No newline at end of file diff --git a/docs/2.12.0/building-the-frontend/index.html b/docs/2.12.0/building-the-frontend/index.html index ca641bace7..3ca545e499 100644 --- a/docs/2.12.0/building-the-frontend/index.html +++ b/docs/2.12.0/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.12.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.12.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.12.0/contributing-guide/index.html b/docs/2.12.0/contributing-guide/index.html index a8349d3032..a0d8af13ad 100644 --- a/docs/2.12.0/contributing-guide/index.html +++ b/docs/2.12.0/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.12.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.12.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.12.0/css-guidelines/index.html b/docs/2.12.0/css-guidelines/index.html index d614c00af1..bf0a515657 100644 --- a/docs/2.12.0/css-guidelines/index.html +++ b/docs/2.12.0/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.12.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.12.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.12.0/discover/index.html b/docs/2.12.0/discover/index.html index da9d9f28a2..a131321db1 100644 --- a/docs/2.12.0/discover/index.html +++ b/docs/2.12.0/discover/index.html @@ -2,13 +2,13 @@ - -Getting started with Richie | Richie - - + +Getting started with Richie | Richie + + -
    Version: 2.12.0

    Getting started with Richie

    If you're looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    +
    Version: 2.12.0

    Getting started with Richie

    If you're looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    Login/password are admin/admin. The database is regularly flushed.

    Architecture

    Richie is a container-native application but can also be installed @@ -55,6 +55,6 @@

    This approach is used for example on https://www.fun-campus.fr or https://catalogue.edulib.org.

    For a seamless user experience, it is possible to connect a Richie instance to an OpenEdX instance (or some other LMS like Moodle at the cost of minor adaptations), in several ways that we explain in -the LMS connection guide.

    +the LMS connection guide.

    \ No newline at end of file diff --git a/docs/2.12.0/displaying-connection-status/index.html b/docs/2.12.0/displaying-connection-status/index.html index 3f0b91be41..58e998a23c 100644 --- a/docs/2.12.0/displaying-connection-status/index.html +++ b/docs/2.12.0/displaying-connection-status/index.html @@ -2,10 +2,10 @@ - -Displaying OpenEdX connection status in Richie | Richie - - + +Displaying OpenEdX connection status in Richie | Richie + + +
    \ No newline at end of file diff --git a/docs/2.12.0/django-react-interop/index.html b/docs/2.12.0/django-react-interop/index.html index dd735bef10..9fb5dc2a0f 100644 --- a/docs/2.12.0/django-react-interop/index.html +++ b/docs/2.12.0/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.12.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.12.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -64,6 +64,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.12.0/docker-development/index.html b/docs/2.12.0/docker-development/index.html index 47cbb927aa..afda2e8851 100644 --- a/docs/2.12.0/docker-development/index.html +++ b/docs/2.12.0/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.12.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.12.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.12.0/frontend-overrides/index.html b/docs/2.12.0/frontend-overrides/index.html index cf04118010..4328314a16 100644 --- a/docs/2.12.0/frontend-overrides/index.html +++ b/docs/2.12.0/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.12.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.12.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.12.0/internationalization/index.html b/docs/2.12.0/internationalization/index.html index e6f0994be5..865ffa97f0 100644 --- a/docs/2.12.0/internationalization/index.html +++ b/docs/2.12.0/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.12.0

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.12.0

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.12.0/lms-backends/index.html b/docs/2.12.0/lms-backends/index.html index 5510fb6949..cd4f21222f 100644 --- a/docs/2.12.0/lms-backends/index.html +++ b/docs/2.12.0/lms-backends/index.html @@ -2,10 +2,10 @@ - -Configuring LMS Backends | Richie - - + +Configuring LMS Backends | Richie + +
    Version: 2.12.0

    Configuring LMS Backends

    Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless @@ -115,6 +115,6 @@

    Technical

    If you encounter an issue with this documentation or the backends included in Richie, please open an issue on our repository.

    If you need a custom backend, you can submit a PR or -open an issue and we will consider adding it.

    +open an issue and we will consider adding it.

    \ No newline at end of file diff --git a/docs/2.12.0/lms-connection/index.html b/docs/2.12.0/lms-connection/index.html index 25d6f3b626..2d9bf89522 100644 --- a/docs/2.12.0/lms-connection/index.html +++ b/docs/2.12.0/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with one or more LMS | Richie - - + +Connecting Richie with one or more LMS | Richie + + -
    Version: 2.12.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    +
    Version: 2.12.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    Richie can be connected to an LMS in several ways, ranging from SSO to a fully integrated seamless experience.

    As of today, each approach has been implemented for OpenEdX but the same could be done for @@ -63,6 +63,6 @@

    Development

    If you want to activate seamless enrollment locally for development, you will need to set up TLS domains for both Richie and OpenEdX. To do this, head over to our -guide on setting-up TLS connections for Richie and OpenEdX.

    +guide on setting-up TLS connections for Richie and OpenEdX.

    \ No newline at end of file diff --git a/docs/2.12.0/native-installation/index.html b/docs/2.12.0/native-installation/index.html index 493612ebc1..090f9e455e 100644 --- a/docs/2.12.0/native-installation/index.html +++ b/docs/2.12.0/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.12.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.12.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.12.0/synchronizing-course-runs/index.html b/docs/2.12.0/synchronizing-course-runs/index.html index aeff1c8423..072f4e39bc 100644 --- a/docs/2.12.0/synchronizing-course-runs/index.html +++ b/docs/2.12.0/synchronizing-course-runs/index.html @@ -2,10 +2,10 @@ - -Synchronizing course runs between Richie and OpenEdX | Richie - - + +Synchronizing course runs between Richie and OpenEdX | Richie + +
    Version: 2.12.0

    Synchronizing course runs between Richie and OpenEdX

    Richie can receive automatic course runs updates on a dedicated API endpoint.

    @@ -51,6 +51,6 @@

    import hashlib
    import hmac
    import json

    from django.conf import settings

    from microsite_configuration import microsite
    import requests
    from xmodule.modulestore.django import modulestore


    def update_course(course_key, *args, **kwargs):
    """Synchronize an OpenEdX course, identified by its course key, with a Richie instance."""
    course = modulestore().get_course(course_key)
    edxapp_domain = microsite.get_value("site_domain", settings.LMS_BASE)

    data = {
    "resource_link": "https://{:s}/courses/{!s}/info".format(
    edxapp_domain, course_key
    ),
    "start": course.start and course.start.isoformat(),
    "end": course.end and course.end.isoformat(),
    "enrollment_start": course.enrollment_start and course.enrollment_start.isoformat(),
    "enrollment_end": course.enrollment_end and course.enrollment_end.isoformat(),
    "languages": [course.language or settings.LANGUAGE_CODE],
    }

    signature = hmac.new(
    setting.COURSE_HOOK["secret"].encode("utf-8"),
    msg=json.dumps(data).encode("utf-8"),
    digestmod=hashlib.sha256,
    ).hexdigest()

    response = requests.post(
    setting.COURSE_HOOK["url"],
    json=data,
    headers={"Authorization": "SIG-HMAC-SHA256 {:s}".format(signature)},
    )

    Thanks to the signal emitted in OpenEdX, this function can then be triggered each time a course is modified and published:

    -
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    +
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    \ No newline at end of file diff --git a/docs/2.12.0/tls-connection/index.html b/docs/2.12.0/tls-connection/index.html index 4dfc43c181..6a91390238 100644 --- a/docs/2.12.0/tls-connection/index.html +++ b/docs/2.12.0/tls-connection/index.html @@ -2,10 +2,10 @@ - -Connecting Richie and OpenEdX over TLS for development | Richie - - + +Connecting Richie and OpenEdX over TLS for development | Richie + +
    Version: 2.12.0

    Connecting Richie and OpenEdX over TLS for development

    Purpose

    @@ -68,6 +68,6 @@

    $ make run-ssl

    Of course, you can still run apps without ssl by using:

    -
    $ make run
    +
    $ make run
    \ No newline at end of file diff --git a/docs/2.12.0/web-analytics/index.html b/docs/2.12.0/web-analytics/index.html index 1d73ade4b1..11a3fb256f 100644 --- a/docs/2.12.0/web-analytics/index.html +++ b/docs/2.12.0/web-analytics/index.html @@ -2,13 +2,13 @@ - -Add web analytics to your site | Richie - - + +Add web analytics to your site | Richie + + -
    Version: 2.12.0

    Add web analytics to your site

    The purpose of this file is to document how you can enable a Web Analytics solution. +

    Version: 2.12.0

    Add web analytics to your site

    The purpose of this file is to document how you can enable a Web Analytics solution. Currently Richie only supports by default the Google Analytics using the Google Tag Manager Javascript. But it is possible with little cost to add support for other web analytics solutions.

    Google Analytics

    @@ -53,6 +53,6 @@

    <script type="text/javascript">
    console.log("organization codes: '{{ WEB_ANALYTICS.DIMENSIONS.organizations_codes |join:" | " }}");
    </script>

    +
    <script type="text/javascript">
    console.log("organization codes: '{{ WEB_ANALYTICS.DIMENSIONS.organizations_codes |join:" | " }}");
    </script>
    \ No newline at end of file diff --git a/docs/2.13.0/accessibility-testing/index.html b/docs/2.13.0/accessibility-testing/index.html index 4b1327bf89..699c10cdf8 100644 --- a/docs/2.13.0/accessibility-testing/index.html +++ b/docs/2.13.0/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.13.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.13.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems in any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.13.0/api/course-run-synchronization-api/index.html b/docs/2.13.0/api/course-run-synchronization-api/index.html index bc631f808e..6be2296fe1 100644 --- a/docs/2.13.0/api/course-run-synchronization-api/index.html +++ b/docs/2.13.0/api/course-run-synchronization-api/index.html @@ -2,10 +2,10 @@ - -Course run synchronization API | Richie - - + +Course run synchronization API | Richie + +
    Version: 2.13.0

    Course run synchronization API

    API endpoint allowing remote systems to synchronize their course runs with a Richie instance.

    @@ -52,6 +52,6 @@

    +
    \ No newline at end of file diff --git a/docs/2.13.0/building-the-frontend/index.html b/docs/2.13.0/building-the-frontend/index.html index 2d3abb8f84..5e1480c889 100644 --- a/docs/2.13.0/building-the-frontend/index.html +++ b/docs/2.13.0/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.13.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.13.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.13.0/contributing-guide/index.html b/docs/2.13.0/contributing-guide/index.html index d31ff6cbd0..8c91b5bea1 100644 --- a/docs/2.13.0/contributing-guide/index.html +++ b/docs/2.13.0/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.13.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.13.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.13.0/css-guidelines/index.html b/docs/2.13.0/css-guidelines/index.html index 432a4688c4..f5328de4e1 100644 --- a/docs/2.13.0/css-guidelines/index.html +++ b/docs/2.13.0/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.13.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.13.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.13.0/discover/index.html b/docs/2.13.0/discover/index.html index 4e152f6f4f..52cae9c896 100644 --- a/docs/2.13.0/discover/index.html +++ b/docs/2.13.0/discover/index.html @@ -2,13 +2,13 @@ - -Getting started with Richie | Richie - - + +Getting started with Richie | Richie + + -
    Version: 2.13.0

    Getting started with Richie

    If you're looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    +
    Version: 2.13.0

    Getting started with Richie

    If you're looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    Login/password are admin/admin. The database is regularly flushed.

    Architecture

    Richie is a container-native application but can also be installed @@ -55,6 +55,6 @@

    This approach is used for example on https://www.fun-campus.fr or https://catalogue.edulib.org.

    For a seamless user experience, it is possible to connect a Richie instance to an OpenEdX instance (or some other LMS like Moodle at the cost of minor adaptations), in several ways that we explain in -the LMS connection guide.

    +the LMS connection guide.

    \ No newline at end of file diff --git a/docs/2.13.0/displaying-connection-status/index.html b/docs/2.13.0/displaying-connection-status/index.html index b6a03c1d9c..9e4c879447 100644 --- a/docs/2.13.0/displaying-connection-status/index.html +++ b/docs/2.13.0/displaying-connection-status/index.html @@ -2,10 +2,10 @@ - -Displaying OpenEdX connection status in Richie | Richie - - + +Displaying OpenEdX connection status in Richie | Richie + + +
    \ No newline at end of file diff --git a/docs/2.13.0/django-react-interop/index.html b/docs/2.13.0/django-react-interop/index.html index d0c72efcd1..ae93a61a43 100644 --- a/docs/2.13.0/django-react-interop/index.html +++ b/docs/2.13.0/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.13.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.13.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -64,6 +64,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.13.0/docker-development/index.html b/docs/2.13.0/docker-development/index.html index 6d2f9e1480..433f33ca57 100644 --- a/docs/2.13.0/docker-development/index.html +++ b/docs/2.13.0/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.13.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.13.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.13.0/frontend-overrides/index.html b/docs/2.13.0/frontend-overrides/index.html index f6e2eaca3d..fe422d2389 100644 --- a/docs/2.13.0/frontend-overrides/index.html +++ b/docs/2.13.0/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.13.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.13.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.13.0/internationalization/index.html b/docs/2.13.0/internationalization/index.html index cc34abbe7f..f627b35a70 100644 --- a/docs/2.13.0/internationalization/index.html +++ b/docs/2.13.0/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.13.0

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.13.0

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.13.0/lms-backends/index.html b/docs/2.13.0/lms-backends/index.html index 5b21344b71..2d4cf05c2c 100644 --- a/docs/2.13.0/lms-backends/index.html +++ b/docs/2.13.0/lms-backends/index.html @@ -2,10 +2,10 @@ - -Configuring LMS Backends | Richie - - + +Configuring LMS Backends | Richie + +
    Version: 2.13.0

    Configuring LMS Backends

    Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless @@ -115,6 +115,6 @@

    Technical

    If you encounter an issue with this documentation or the backends included in Richie, please open an issue on our repository.

    If you need a custom backend, you can submit a PR or -open an issue and we will consider adding it.

    +open an issue and we will consider adding it.

    \ No newline at end of file diff --git a/docs/2.13.0/lms-connection/index.html b/docs/2.13.0/lms-connection/index.html index dcbd7621d6..aec4171e0a 100644 --- a/docs/2.13.0/lms-connection/index.html +++ b/docs/2.13.0/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with one or more LMS | Richie - - + +Connecting Richie with one or more LMS | Richie + + -
    Version: 2.13.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    +
    Version: 2.13.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    Richie can be connected to an LMS in several ways, ranging from SSO to a fully integrated seamless experience.

    As of today, each approach has been implemented for OpenEdX but the same could be done for @@ -63,6 +63,6 @@

    Development

    If you want to activate seamless enrollment locally for development, you will need to set up TLS domains for both Richie and OpenEdX. To do this, head over to our -guide on setting-up TLS connections for Richie and OpenEdX.

    +guide on setting-up TLS connections for Richie and OpenEdX.

    \ No newline at end of file diff --git a/docs/2.13.0/native-installation/index.html b/docs/2.13.0/native-installation/index.html index 60193a5fac..4ebe052a84 100644 --- a/docs/2.13.0/native-installation/index.html +++ b/docs/2.13.0/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.13.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.13.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.13.0/synchronizing-course-runs/index.html b/docs/2.13.0/synchronizing-course-runs/index.html index 96ffc2f317..1d8e633ec7 100644 --- a/docs/2.13.0/synchronizing-course-runs/index.html +++ b/docs/2.13.0/synchronizing-course-runs/index.html @@ -2,10 +2,10 @@ - -Synchronizing course runs between Richie and OpenEdX | Richie - - + +Synchronizing course runs between Richie and OpenEdX | Richie + +
    Version: 2.13.0

    Synchronizing course runs between Richie and OpenEdX

    Richie can receive automatic course runs updates on a dedicated API endpoint.

    @@ -51,6 +51,6 @@

    import hashlib
    import hmac
    import json

    from django.conf import settings

    from microsite_configuration import microsite
    import requests
    from xmodule.modulestore.django import modulestore


    def update_course(course_key, *args, **kwargs):
    """Synchronize an OpenEdX course, identified by its course key, with a Richie instance."""
    course = modulestore().get_course(course_key)
    edxapp_domain = microsite.get_value("site_domain", settings.LMS_BASE)

    data = {
    "resource_link": "https://{:s}/courses/{!s}/info".format(
    edxapp_domain, course_key
    ),
    "start": course.start and course.start.isoformat(),
    "end": course.end and course.end.isoformat(),
    "enrollment_start": course.enrollment_start and course.enrollment_start.isoformat(),
    "enrollment_end": course.enrollment_end and course.enrollment_end.isoformat(),
    "languages": [course.language or settings.LANGUAGE_CODE],
    }

    signature = hmac.new(
    setting.COURSE_HOOK["secret"].encode("utf-8"),
    msg=json.dumps(data).encode("utf-8"),
    digestmod=hashlib.sha256,
    ).hexdigest()

    response = requests.post(
    setting.COURSE_HOOK["url"],
    json=data,
    headers={"Authorization": "SIG-HMAC-SHA256 {:s}".format(signature)},
    )

    Thanks to the signal emitted in OpenEdX, this function can then be triggered each time a course is modified and published:

    -
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    +
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    \ No newline at end of file diff --git a/docs/2.13.0/tls-connection/index.html b/docs/2.13.0/tls-connection/index.html index 25d043b43a..80eea4f591 100644 --- a/docs/2.13.0/tls-connection/index.html +++ b/docs/2.13.0/tls-connection/index.html @@ -2,10 +2,10 @@ - -Connecting Richie and OpenEdX over TLS for development | Richie - - + +Connecting Richie and OpenEdX over TLS for development | Richie + +
    Version: 2.13.0

    Connecting Richie and OpenEdX over TLS for development

    Purpose

    @@ -68,6 +68,6 @@

    $ make run-ssl

    Of course, you can still run apps without ssl by using:

    -
    $ make run
    +
    $ make run
    \ No newline at end of file diff --git a/docs/2.13.0/web-analytics/index.html b/docs/2.13.0/web-analytics/index.html index cbf151ab02..1a1182a6c7 100644 --- a/docs/2.13.0/web-analytics/index.html +++ b/docs/2.13.0/web-analytics/index.html @@ -2,13 +2,13 @@ - -Add web analytics to your site | Richie - - + +Add web analytics to your site | Richie + + -
    Version: 2.13.0

    Add web analytics to your site

    The purpose of this file is to document how you can enable a Web Analytics solution. +

    Version: 2.13.0

    Add web analytics to your site

    The purpose of this file is to document how you can enable a Web Analytics solution. Currently Richie only supports by default the Google Analytics using the Google Tag Manager Javascript. But it is possible with little cost to add support for other web analytics solutions.

    Google Analytics

    @@ -53,6 +53,6 @@

    <script type="text/javascript">
    console.log("organization codes: '{{ WEB_ANALYTICS.DIMENSIONS.organizations_codes |join:" | " }}");
    </script>

    +
    <script type="text/javascript">
    console.log("organization codes: '{{ WEB_ANALYTICS.DIMENSIONS.organizations_codes |join:" | " }}");
    </script>
    \ No newline at end of file diff --git a/docs/2.14.0/accessibility-testing/index.html b/docs/2.14.0/accessibility-testing/index.html index 1a26ceb952..04cd400be9 100644 --- a/docs/2.14.0/accessibility-testing/index.html +++ b/docs/2.14.0/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.14.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.14.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems in any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.14.0/api/course-run-synchronization-api/index.html b/docs/2.14.0/api/course-run-synchronization-api/index.html index 29234d5208..2e52147597 100644 --- a/docs/2.14.0/api/course-run-synchronization-api/index.html +++ b/docs/2.14.0/api/course-run-synchronization-api/index.html @@ -2,10 +2,10 @@ - -Course run synchronization API | Richie - - + +Course run synchronization API | Richie + +
    Version: 2.14.0

    Course run synchronization API

    API endpoint allowing remote systems to synchronize their course runs with a Richie instance.

    @@ -52,6 +52,6 @@

    +
    \ No newline at end of file diff --git a/docs/2.14.0/building-the-frontend/index.html b/docs/2.14.0/building-the-frontend/index.html index 2de3c7cfd0..39ba9b1f4a 100644 --- a/docs/2.14.0/building-the-frontend/index.html +++ b/docs/2.14.0/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.14.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.14.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.14.0/contributing-guide/index.html b/docs/2.14.0/contributing-guide/index.html index 745e1d3a6b..d421794751 100644 --- a/docs/2.14.0/contributing-guide/index.html +++ b/docs/2.14.0/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.14.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.14.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.14.0/css-guidelines/index.html b/docs/2.14.0/css-guidelines/index.html index 4ddb2f0ad2..0a3adea7f1 100644 --- a/docs/2.14.0/css-guidelines/index.html +++ b/docs/2.14.0/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.14.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.14.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.14.0/discover/index.html b/docs/2.14.0/discover/index.html index 6f9b91dd9a..081adb580d 100644 --- a/docs/2.14.0/discover/index.html +++ b/docs/2.14.0/discover/index.html @@ -2,13 +2,13 @@ - -Getting started with Richie | Richie - - + +Getting started with Richie | Richie + + -
    Version: 2.14.0

    Getting started with Richie

    If you're looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    +
    Version: 2.14.0

    Getting started with Richie

    If you're looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    Login/password are admin/admin. The database is regularly flushed.

    Architecture

    Richie is a container-native application but can also be installed @@ -55,6 +55,6 @@

    This approach is used for example on https://www.fun-campus.fr or https://catalogue.edulib.org.

    For a seamless user experience, it is possible to connect a Richie instance to an OpenEdX instance (or some other LMS like Moodle at the cost of minor adaptations), in several ways that we explain in -the LMS connection guide.

    +the LMS connection guide.

    \ No newline at end of file diff --git a/docs/2.14.0/displaying-connection-status/index.html b/docs/2.14.0/displaying-connection-status/index.html index fecc6abd81..ab4445efcf 100644 --- a/docs/2.14.0/displaying-connection-status/index.html +++ b/docs/2.14.0/displaying-connection-status/index.html @@ -2,10 +2,10 @@ - -Displaying OpenEdX connection status in Richie | Richie - - + +Displaying OpenEdX connection status in Richie | Richie + + +
    \ No newline at end of file diff --git a/docs/2.14.0/django-react-interop/index.html b/docs/2.14.0/django-react-interop/index.html index 85e1e68ada..d7193416f8 100644 --- a/docs/2.14.0/django-react-interop/index.html +++ b/docs/2.14.0/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.14.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.14.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -64,6 +64,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.14.0/docker-development/index.html b/docs/2.14.0/docker-development/index.html index 5063df8dc3..ab2a2dcff3 100644 --- a/docs/2.14.0/docker-development/index.html +++ b/docs/2.14.0/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.14.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.14.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.14.0/frontend-overrides/index.html b/docs/2.14.0/frontend-overrides/index.html index cff557e719..7dd0be058f 100644 --- a/docs/2.14.0/frontend-overrides/index.html +++ b/docs/2.14.0/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.14.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.14.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.14.0/internationalization/index.html b/docs/2.14.0/internationalization/index.html index d5b79a1d56..7ee6c9d915 100644 --- a/docs/2.14.0/internationalization/index.html +++ b/docs/2.14.0/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.14.0

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.14.0

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.14.0/lms-backends/index.html b/docs/2.14.0/lms-backends/index.html index 96802cfd6a..dc8be80fbb 100644 --- a/docs/2.14.0/lms-backends/index.html +++ b/docs/2.14.0/lms-backends/index.html @@ -2,10 +2,10 @@ - -Configuring LMS Backends | Richie - - + +Configuring LMS Backends | Richie + +
    Version: 2.14.0

    Configuring LMS Backends

    Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless @@ -115,6 +115,6 @@

    Technical

    If you encounter an issue with this documentation or the backends included in Richie, please open an issue on our repository.

    If you need a custom backend, you can submit a PR or -open an issue and we will consider adding it.

    +open an issue and we will consider adding it.

    \ No newline at end of file diff --git a/docs/2.14.0/lms-connection/index.html b/docs/2.14.0/lms-connection/index.html index 0e61cc575e..af95da4e43 100644 --- a/docs/2.14.0/lms-connection/index.html +++ b/docs/2.14.0/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with one or more LMS | Richie - - + +Connecting Richie with one or more LMS | Richie + + -
    Version: 2.14.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    +
    Version: 2.14.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    Richie can be connected to an LMS in several ways, ranging from SSO to a fully integrated seamless experience.

    As of today, each approach has been implemented for OpenEdX but the same could be done for @@ -63,6 +63,6 @@

    Development

    If you want to activate seamless enrollment locally for development, you will need to set up TLS domains for both Richie and OpenEdX. To do this, head over to our -guide on setting-up TLS connections for Richie and OpenEdX.

    +guide on setting-up TLS connections for Richie and OpenEdX.

    \ No newline at end of file diff --git a/docs/2.14.0/native-installation/index.html b/docs/2.14.0/native-installation/index.html index 8d987471b6..f0cdd20abd 100644 --- a/docs/2.14.0/native-installation/index.html +++ b/docs/2.14.0/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.14.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.14.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.14.0/synchronizing-course-runs/index.html b/docs/2.14.0/synchronizing-course-runs/index.html index 84a580cc23..31a029fd4a 100644 --- a/docs/2.14.0/synchronizing-course-runs/index.html +++ b/docs/2.14.0/synchronizing-course-runs/index.html @@ -2,10 +2,10 @@ - -Synchronizing course runs between Richie and OpenEdX | Richie - - + +Synchronizing course runs between Richie and OpenEdX | Richie + +
    Version: 2.14.0

    Synchronizing course runs between Richie and OpenEdX

    Richie can receive automatic course runs updates on a dedicated API endpoint.

    @@ -51,6 +51,6 @@

    import hashlib
    import hmac
    import json

    from django.conf import settings

    from microsite_configuration import microsite
    import requests
    from xmodule.modulestore.django import modulestore


    def update_course(course_key, *args, **kwargs):
    """Synchronize an OpenEdX course, identified by its course key, with a Richie instance."""
    course = modulestore().get_course(course_key)
    edxapp_domain = microsite.get_value("site_domain", settings.LMS_BASE)

    data = {
    "resource_link": "https://{:s}/courses/{!s}/info".format(
    edxapp_domain, course_key
    ),
    "start": course.start and course.start.isoformat(),
    "end": course.end and course.end.isoformat(),
    "enrollment_start": course.enrollment_start and course.enrollment_start.isoformat(),
    "enrollment_end": course.enrollment_end and course.enrollment_end.isoformat(),
    "languages": [course.language or settings.LANGUAGE_CODE],
    }

    signature = hmac.new(
    setting.COURSE_HOOK["secret"].encode("utf-8"),
    msg=json.dumps(data).encode("utf-8"),
    digestmod=hashlib.sha256,
    ).hexdigest()

    response = requests.post(
    setting.COURSE_HOOK["url"],
    json=data,
    headers={"Authorization": "SIG-HMAC-SHA256 {:s}".format(signature)},
    )

    Thanks to the signal emitted in OpenEdX, this function can then be triggered each time a course is modified and published:

    -
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    +
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    \ No newline at end of file diff --git a/docs/2.14.0/tls-connection/index.html b/docs/2.14.0/tls-connection/index.html index 5ef4c2a5d2..3295c573e5 100644 --- a/docs/2.14.0/tls-connection/index.html +++ b/docs/2.14.0/tls-connection/index.html @@ -2,10 +2,10 @@ - -Connecting Richie and OpenEdX over TLS for development | Richie - - + +Connecting Richie and OpenEdX over TLS for development | Richie + +
    Version: 2.14.0

    Connecting Richie and OpenEdX over TLS for development

    Purpose

    @@ -68,6 +68,6 @@

    $ make run-ssl

    Of course, you can still run apps without ssl by using:

    -
    $ make run
    +
    $ make run
    \ No newline at end of file diff --git a/docs/2.14.0/web-analytics/index.html b/docs/2.14.0/web-analytics/index.html index fd5585b06b..a88df66513 100644 --- a/docs/2.14.0/web-analytics/index.html +++ b/docs/2.14.0/web-analytics/index.html @@ -2,13 +2,13 @@ - -Add web analytics to your site | Richie - - + +Add web analytics to your site | Richie + + -
    Version: 2.14.0

    Add web analytics to your site

    Richie has native support to Google Analytics and Google Tag Manager Web Analytics solutions. +

    Version: 2.14.0

    Add web analytics to your site

    Richie has native support to Google Analytics and Google Tag Manager Web Analytics solutions. The purpose of this file is to explain how you can enable one of the supported Web Analytics providers and how you can extend Richie with an alternative solution.

    Google Analytics

    @@ -64,6 +64,6 @@

    +of src/frontend/js/utils/api/web-analytics/google_analytics.ts and change the src/frontend/js/utils/api/web-analytics/index.ts file to include that newer provider.

    \ No newline at end of file diff --git a/docs/2.14.1/accessibility-testing/index.html b/docs/2.14.1/accessibility-testing/index.html index e00182f8a9..76e1ee9ce9 100644 --- a/docs/2.14.1/accessibility-testing/index.html +++ b/docs/2.14.1/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.14.1

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.14.1

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems in any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.14.1/api/course-run-synchronization-api/index.html b/docs/2.14.1/api/course-run-synchronization-api/index.html index 9ff67b088e..64356fd7c3 100644 --- a/docs/2.14.1/api/course-run-synchronization-api/index.html +++ b/docs/2.14.1/api/course-run-synchronization-api/index.html @@ -2,10 +2,10 @@ - -Course run synchronization API | Richie - - + +Course run synchronization API | Richie + +
    Version: 2.14.1

    Course run synchronization API

    API endpoint allowing remote systems to synchronize their course runs with a Richie instance.

    @@ -52,6 +52,6 @@

    +
    \ No newline at end of file diff --git a/docs/2.14.1/building-the-frontend/index.html b/docs/2.14.1/building-the-frontend/index.html index ab20b66e06..f65e5346cf 100644 --- a/docs/2.14.1/building-the-frontend/index.html +++ b/docs/2.14.1/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.14.1

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.14.1

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.14.1/contributing-guide/index.html b/docs/2.14.1/contributing-guide/index.html index bf9675ca13..23d239ad1e 100644 --- a/docs/2.14.1/contributing-guide/index.html +++ b/docs/2.14.1/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.14.1

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.14.1

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.14.1/cookiecutter/index.html b/docs/2.14.1/cookiecutter/index.html index 930a531956..09d15ad3e5 100644 --- a/docs/2.14.1/cookiecutter/index.html +++ b/docs/2.14.1/cookiecutter/index.html @@ -2,13 +2,13 @@ - -Start your own site | Richie - - + +Start your own site | Richie + + -
    Version: 2.14.1

    Start your own site

    We use Cookiecutter to help you +

    Version: 2.14.1

    Start your own site

    We use Cookiecutter to help you set up a production-ready learning portal website based on Richie in seconds.

    Run Cookiecutter

    @@ -68,6 +68,6 @@

    cookiecutter --overwrite-if-exists gh:openfun/richie --directory=cookiecutter

    Help us improve this project

    After starting your project, please submit an issue let us know how it went and -what other features we should add to make it better.

    +what other features we should add to make it better.

    \ No newline at end of file diff --git a/docs/2.14.1/css-guidelines/index.html b/docs/2.14.1/css-guidelines/index.html index 559d59fd14..53227a08fe 100644 --- a/docs/2.14.1/css-guidelines/index.html +++ b/docs/2.14.1/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.14.1

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.14.1

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.14.1/discover/index.html b/docs/2.14.1/discover/index.html index 1b4a790ab6..9a775e3146 100644 --- a/docs/2.14.1/discover/index.html +++ b/docs/2.14.1/discover/index.html @@ -2,10 +2,10 @@ - -Discover Richie | Richie - - + +Discover Richie | Richie + +
    Version: 2.14.1

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online @@ -51,6 +51,6 @@

    Start yo
  • override some css rules or rebuild the whole css with your own variables and customizations,
  • add any DjangoCMS plugin or feature,
  • add any Django third-party application.
  • -

    +
    \ No newline at end of file diff --git a/docs/2.14.1/displaying-connection-status/index.html b/docs/2.14.1/displaying-connection-status/index.html index dff55efcc2..9843974735 100644 --- a/docs/2.14.1/displaying-connection-status/index.html +++ b/docs/2.14.1/displaying-connection-status/index.html @@ -2,10 +2,10 @@ - -Displaying OpenEdX connection status in Richie | Richie - - + +Displaying OpenEdX connection status in Richie | Richie + + +
    \ No newline at end of file diff --git a/docs/2.14.1/django-react-interop/index.html b/docs/2.14.1/django-react-interop/index.html index b8476bbcd5..b06f30a0bd 100644 --- a/docs/2.14.1/django-react-interop/index.html +++ b/docs/2.14.1/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.14.1

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.14.1

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -64,6 +64,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.14.1/docker-development/index.html b/docs/2.14.1/docker-development/index.html index 2ad61bb7f7..58e5e8b847 100644 --- a/docs/2.14.1/docker-development/index.html +++ b/docs/2.14.1/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.14.1

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.14.1

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.14.1/frontend-overrides/index.html b/docs/2.14.1/frontend-overrides/index.html index ff757953ef..caffd7556e 100644 --- a/docs/2.14.1/frontend-overrides/index.html +++ b/docs/2.14.1/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.14.1

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.14.1

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.14.1/installation/index.html b/docs/2.14.1/installation/index.html index ee86c0ad50..9c5aba1390 100644 --- a/docs/2.14.1/installation/index.html +++ b/docs/2.14.1/installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie for development | Richie - - + +Installing Richie for development | Richie + + -
    Version: 2.14.1

    Installing Richie for development

    Richie is a container-native application but can also be installed +

    +https://www.nau.edu.pt.

    \ No newline at end of file diff --git a/docs/2.14.1/internationalization/index.html b/docs/2.14.1/internationalization/index.html index 40217658d7..ee68bc333f 100644 --- a/docs/2.14.1/internationalization/index.html +++ b/docs/2.14.1/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.14.1

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.14.1

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.14.1/joanie-connection/index.html b/docs/2.14.1/joanie-connection/index.html index 5ccc8284b7..5e43328f2d 100644 --- a/docs/2.14.1/joanie-connection/index.html +++ b/docs/2.14.1/joanie-connection/index.html @@ -2,10 +2,10 @@ - -Joanie Connection | Richie - - + +Joanie Connection | Richie + +
    Version: 2.14.1

    Joanie Connection

    @@ -28,6 +28,6 @@

    Lifet

    To always have a valid access token, you have to configure properly its stale time according to the lifetime of the access token defined by your authentication server. For example, if your authentication server is using djangorestframework-simplejwt to generate the access token, -its lifetime is 5 minutes by default.

    +its lifetime is 5 minutes by default.

    \ No newline at end of file diff --git a/docs/2.14.1/lms-backends/index.html b/docs/2.14.1/lms-backends/index.html index b830c4bded..fb50a0eb4d 100644 --- a/docs/2.14.1/lms-backends/index.html +++ b/docs/2.14.1/lms-backends/index.html @@ -2,10 +2,10 @@ - -Configuring LMS Backends | Richie - - + +Configuring LMS Backends | Richie + +
    Version: 2.14.1

    Configuring LMS Backends

    Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless @@ -115,6 +115,6 @@

    Technical

    If you encounter an issue with this documentation or the backends included in Richie, please open an issue on our repository.

    If you need a custom backend, you can submit a PR or -open an issue and we will consider adding it.

    +open an issue and we will consider adding it.

    \ No newline at end of file diff --git a/docs/2.14.1/lms-connection/index.html b/docs/2.14.1/lms-connection/index.html index 3b3637bd91..a9a9d89856 100644 --- a/docs/2.14.1/lms-connection/index.html +++ b/docs/2.14.1/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with one or more LMS | Richie - - + +Connecting Richie with one or more LMS | Richie + + -
    Version: 2.14.1

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    +
    Version: 2.14.1

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    Richie can be connected to an LMS in several ways, ranging from SSO to a fully integrated seamless experience.

    As of today, each approach has been implemented for OpenEdX but the same could be done for @@ -63,6 +63,6 @@

    Development

    If you want to activate seamless enrollment locally for development, you will need to set up TLS domains for both Richie and OpenEdX. To do this, head over to our -guide on setting-up TLS connections for Richie and OpenEdX.

    +guide on setting-up TLS connections for Richie and OpenEdX.

    \ No newline at end of file diff --git a/docs/2.14.1/native-installation/index.html b/docs/2.14.1/native-installation/index.html index b2d162cfd9..221de8199b 100644 --- a/docs/2.14.1/native-installation/index.html +++ b/docs/2.14.1/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.14.1

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.14.1

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native installation instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.14.1/synchronizing-course-runs/index.html b/docs/2.14.1/synchronizing-course-runs/index.html index 7258b61ecf..3665599bec 100644 --- a/docs/2.14.1/synchronizing-course-runs/index.html +++ b/docs/2.14.1/synchronizing-course-runs/index.html @@ -2,10 +2,10 @@ - -Synchronizing course runs between Richie and OpenEdX | Richie - - + +Synchronizing course runs between Richie and OpenEdX | Richie + +
    Version: 2.14.1

    Synchronizing course runs between Richie and OpenEdX

    Richie can receive automatic course runs updates on a dedicated API endpoint.

    @@ -51,6 +51,6 @@

    import hashlib
    import hmac
    import json

    from django.conf import settings

    from microsite_configuration import microsite
    import requests
    from xmodule.modulestore.django import modulestore


    def update_course(course_key, *args, **kwargs):
    """Synchronize an OpenEdX course, identified by its course key, with a Richie instance."""
    course = modulestore().get_course(course_key)
    edxapp_domain = microsite.get_value("site_domain", settings.LMS_BASE)

    data = {
    "resource_link": "https://{:s}/courses/{!s}/info".format(
    edxapp_domain, course_key
    ),
    "start": course.start and course.start.isoformat(),
    "end": course.end and course.end.isoformat(),
    "enrollment_start": course.enrollment_start and course.enrollment_start.isoformat(),
    "enrollment_end": course.enrollment_end and course.enrollment_end.isoformat(),
    "languages": [course.language or settings.LANGUAGE_CODE],
    }

    signature = hmac.new(
    setting.COURSE_HOOK["secret"].encode("utf-8"),
    msg=json.dumps(data).encode("utf-8"),
    digestmod=hashlib.sha256,
    ).hexdigest()

    response = requests.post(
    setting.COURSE_HOOK["url"],
    json=data,
    headers={"Authorization": "SIG-HMAC-SHA256 {:s}".format(signature)},
    )

    Thanks to the signal emitted in OpenEdX, this function can then be triggered each time a course is modified and published:

    -
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    +
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    \ No newline at end of file diff --git a/docs/2.14.1/tls-connection/index.html b/docs/2.14.1/tls-connection/index.html index 5cef657303..cbf090975d 100644 --- a/docs/2.14.1/tls-connection/index.html +++ b/docs/2.14.1/tls-connection/index.html @@ -2,10 +2,10 @@ - -Connecting Richie and OpenEdX over TLS for development | Richie - - + +Connecting Richie and OpenEdX over TLS for development | Richie + +
    Version: 2.14.1

    Connecting Richie and OpenEdX over TLS for development

    Purpose

    @@ -68,6 +68,6 @@

    $ make run-ssl

    Of course, you can still run apps without ssl by using:

    -
    $ make run
    +
    $ make run
    \ No newline at end of file diff --git a/docs/2.14.1/web-analytics/index.html b/docs/2.14.1/web-analytics/index.html index c889e28841..211e1f8ea1 100644 --- a/docs/2.14.1/web-analytics/index.html +++ b/docs/2.14.1/web-analytics/index.html @@ -2,13 +2,13 @@ - -Add web analytics to your site | Richie - - + +Add web analytics to your site | Richie + + -
    Version: 2.14.1

    Add web analytics to your site

    Richie has native support to Google Analytics and Google Tag Manager Web Analytics solutions. +

    Version: 2.14.1

    Add web analytics to your site

    Richie has native support to Google Analytics and Google Tag Manager Web Analytics solutions. The purpose of this file is to explain how you can enable one of the supported Web Analytics providers and how you can extend Richie with an alternative solution.

    Google Analytics

    @@ -64,6 +64,6 @@

    +of src/frontend/js/utils/api/web-analytics/google_analytics.ts and change the src/frontend/js/utils/api/web-analytics/index.ts file to include that newer provider.

    \ No newline at end of file diff --git a/docs/2.15.0/accessibility-testing/index.html b/docs/2.15.0/accessibility-testing/index.html index 7f789a176e..42281c2e5b 100644 --- a/docs/2.15.0/accessibility-testing/index.html +++ b/docs/2.15.0/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.15.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.15.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems in any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.15.0/api/course-run-synchronization-api/index.html b/docs/2.15.0/api/course-run-synchronization-api/index.html index 7fb64def37..f86ecb5dd7 100644 --- a/docs/2.15.0/api/course-run-synchronization-api/index.html +++ b/docs/2.15.0/api/course-run-synchronization-api/index.html @@ -2,10 +2,10 @@ - -Course run synchronization API | Richie - - + +Course run synchronization API | Richie + +
    Version: 2.15.0

    Course run synchronization API

    API endpoint allowing remote systems to synchronize their course runs with a Richie instance.

    @@ -52,6 +52,6 @@

    +
    \ No newline at end of file diff --git a/docs/2.15.0/building-the-frontend/index.html b/docs/2.15.0/building-the-frontend/index.html index d0a2358404..44dd807877 100644 --- a/docs/2.15.0/building-the-frontend/index.html +++ b/docs/2.15.0/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.15.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.15.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.15.0/contributing-guide/index.html b/docs/2.15.0/contributing-guide/index.html index 42fe648e66..6d726156d7 100644 --- a/docs/2.15.0/contributing-guide/index.html +++ b/docs/2.15.0/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.15.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.15.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.15.0/cookiecutter/index.html b/docs/2.15.0/cookiecutter/index.html index 94e19e8c91..6bd04e9f02 100644 --- a/docs/2.15.0/cookiecutter/index.html +++ b/docs/2.15.0/cookiecutter/index.html @@ -2,13 +2,13 @@ - -Start your own site | Richie - - + +Start your own site | Richie + + -
    Version: 2.15.0

    Start your own site

    We use Cookiecutter to help you +

    Version: 2.15.0

    Start your own site

    We use Cookiecutter to help you set up a production-ready learning portal website based on Richie in seconds.

    Run Cookiecutter

    @@ -68,6 +68,6 @@

    cookiecutter --overwrite-if-exists gh:openfun/richie --directory=cookiecutter

    Help us improve this project

    After starting your project, please submit an issue let us know how it went and -what other features we should add to make it better.

    +what other features we should add to make it better.

    \ No newline at end of file diff --git a/docs/2.15.0/css-guidelines/index.html b/docs/2.15.0/css-guidelines/index.html index 71be2c55c5..3f3de8718d 100644 --- a/docs/2.15.0/css-guidelines/index.html +++ b/docs/2.15.0/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.15.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.15.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.15.0/discover/index.html b/docs/2.15.0/discover/index.html index 66513824ba..5417114592 100644 --- a/docs/2.15.0/discover/index.html +++ b/docs/2.15.0/discover/index.html @@ -2,13 +2,13 @@ - -Discover Richie | Richie - - + +Discover Richie | Richie + + -
    Version: 2.15.0

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online +

    Version: 2.15.0

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online courses and MOOCs.

    However, if you need to build a complete website with flexible content to aggregate your courses, in several languages and from different sources, you will soon need a CMS.

    @@ -51,6 +51,6 @@

    Start yo
  • override some css rules or rebuild the whole css with your own variables and customizations,
  • add any DjangoCMS plugin or feature,
  • add any Django third-party application.
  • -

    +
    \ No newline at end of file diff --git a/docs/2.15.0/displaying-connection-status/index.html b/docs/2.15.0/displaying-connection-status/index.html index 06fc2dd624..03feea0b0a 100644 --- a/docs/2.15.0/displaying-connection-status/index.html +++ b/docs/2.15.0/displaying-connection-status/index.html @@ -2,10 +2,10 @@ - -Displaying OpenEdX connection status in Richie | Richie - - + +Displaying OpenEdX connection status in Richie | Richie + + +
    \ No newline at end of file diff --git a/docs/2.15.0/django-react-interop/index.html b/docs/2.15.0/django-react-interop/index.html index 09b6ff27d4..75b172b653 100644 --- a/docs/2.15.0/django-react-interop/index.html +++ b/docs/2.15.0/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.15.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.15.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -64,6 +64,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.15.0/docker-development/index.html b/docs/2.15.0/docker-development/index.html index f656974765..692d97edf5 100644 --- a/docs/2.15.0/docker-development/index.html +++ b/docs/2.15.0/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.15.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.15.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.15.0/frontend-overrides/index.html b/docs/2.15.0/frontend-overrides/index.html index 77837c5974..a6d687c528 100644 --- a/docs/2.15.0/frontend-overrides/index.html +++ b/docs/2.15.0/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.15.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.15.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.15.0/installation/index.html b/docs/2.15.0/installation/index.html index 851302ca98..7a7786fdeb 100644 --- a/docs/2.15.0/installation/index.html +++ b/docs/2.15.0/installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie for development | Richie - - + +Installing Richie for development | Richie + + -
    Version: 2.15.0

    Installing Richie for development

    Richie is a container-native application but can also be installed +

    +https://www.nau.edu.pt.

    \ No newline at end of file diff --git a/docs/2.15.0/internationalization/index.html b/docs/2.15.0/internationalization/index.html index 0ef78cef60..03a8a3521e 100644 --- a/docs/2.15.0/internationalization/index.html +++ b/docs/2.15.0/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.15.0

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.15.0

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.15.0/joanie-connection/index.html b/docs/2.15.0/joanie-connection/index.html index 30ce26ce8b..d3544fa605 100644 --- a/docs/2.15.0/joanie-connection/index.html +++ b/docs/2.15.0/joanie-connection/index.html @@ -2,10 +2,10 @@ - -Joanie Connection | Richie - - + +Joanie Connection | Richie + +
    Version: 2.15.0

    Joanie Connection

    @@ -28,6 +28,6 @@

    Lifet

    To always have a valid access token, you have to configure properly its stale time according to the lifetime of the access token defined by your authentication server. For example, if your authentication server is using djangorestframework-simplejwt to generate the access token, -its lifetime is 5 minutes by default.

    +its lifetime is 5 minutes by default.

    \ No newline at end of file diff --git a/docs/2.15.0/lms-backends/index.html b/docs/2.15.0/lms-backends/index.html index 5b33a38e50..177c3cb419 100644 --- a/docs/2.15.0/lms-backends/index.html +++ b/docs/2.15.0/lms-backends/index.html @@ -2,10 +2,10 @@ - -Configuring LMS Backends | Richie - - + +Configuring LMS Backends | Richie + +
    Version: 2.15.0

    Configuring LMS Backends

    Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless @@ -115,6 +115,6 @@

    Technical

    If you encounter an issue with this documentation or the backends included in Richie, please open an issue on our repository.

    If you need a custom backend, you can submit a PR or -open an issue and we will consider adding it.

    +open an issue and we will consider adding it.

    \ No newline at end of file diff --git a/docs/2.15.0/lms-connection/index.html b/docs/2.15.0/lms-connection/index.html index 2483b15598..c3eab6bada 100644 --- a/docs/2.15.0/lms-connection/index.html +++ b/docs/2.15.0/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with one or more LMS | Richie - - + +Connecting Richie with one or more LMS | Richie + + -
    Version: 2.15.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    +
    Version: 2.15.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    Richie can be connected to an LMS in several ways, ranging from SSO to a fully integrated seamless experience.

    As of today, each approach has been implemented for OpenEdX but the same could be done for @@ -63,6 +63,6 @@

    Development

    If you want to activate seamless enrollment locally for development, you will need to set up TLS domains for both Richie and OpenEdX. To do this, head over to our -guide on setting-up TLS connections for Richie and OpenEdX.

    +guide on setting-up TLS connections for Richie and OpenEdX.

    \ No newline at end of file diff --git a/docs/2.15.0/native-installation/index.html b/docs/2.15.0/native-installation/index.html index 3772e2cf75..258045d794 100644 --- a/docs/2.15.0/native-installation/index.html +++ b/docs/2.15.0/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.15.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.15.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native installation instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.15.0/synchronizing-course-runs/index.html b/docs/2.15.0/synchronizing-course-runs/index.html index ebc91c83f0..fdfde598cb 100644 --- a/docs/2.15.0/synchronizing-course-runs/index.html +++ b/docs/2.15.0/synchronizing-course-runs/index.html @@ -2,10 +2,10 @@ - -Synchronizing course runs between Richie and OpenEdX | Richie - - + +Synchronizing course runs between Richie and OpenEdX | Richie + +
    Version: 2.15.0

    Synchronizing course runs between Richie and OpenEdX

    Richie can receive automatic course runs updates on a dedicated API endpoint.

    @@ -51,6 +51,6 @@

    import hashlib
    import hmac
    import json

    from django.conf import settings

    from microsite_configuration import microsite
    import requests
    from xmodule.modulestore.django import modulestore


    def update_course(course_key, *args, **kwargs):
    """Synchronize an OpenEdX course, identified by its course key, with a Richie instance."""
    course = modulestore().get_course(course_key)
    edxapp_domain = microsite.get_value("site_domain", settings.LMS_BASE)

    data = {
    "resource_link": "https://{:s}/courses/{!s}/info".format(
    edxapp_domain, course_key
    ),
    "start": course.start and course.start.isoformat(),
    "end": course.end and course.end.isoformat(),
    "enrollment_start": course.enrollment_start and course.enrollment_start.isoformat(),
    "enrollment_end": course.enrollment_end and course.enrollment_end.isoformat(),
    "languages": [course.language or settings.LANGUAGE_CODE],
    }

    signature = hmac.new(
    setting.COURSE_HOOK["secret"].encode("utf-8"),
    msg=json.dumps(data).encode("utf-8"),
    digestmod=hashlib.sha256,
    ).hexdigest()

    response = requests.post(
    setting.COURSE_HOOK["url"],
    json=data,
    headers={"Authorization": "SIG-HMAC-SHA256 {:s}".format(signature)},
    )

    Thanks to the signal emitted in OpenEdX, this function can then be triggered each time a course is modified and published:

    -
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    +
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    \ No newline at end of file diff --git a/docs/2.15.0/tls-connection/index.html b/docs/2.15.0/tls-connection/index.html index 8786159934..add40f1eb6 100644 --- a/docs/2.15.0/tls-connection/index.html +++ b/docs/2.15.0/tls-connection/index.html @@ -2,10 +2,10 @@ - -Connecting Richie and OpenEdX over TLS for development | Richie - - + +Connecting Richie and OpenEdX over TLS for development | Richie + +
    Version: 2.15.0

    Connecting Richie and OpenEdX over TLS for development

    Purpose

    @@ -68,6 +68,6 @@

    $ make run-ssl

    Of course, you can still run apps without ssl by using:

    -
    $ make run
    +
    $ make run
    \ No newline at end of file diff --git a/docs/2.15.0/web-analytics/index.html b/docs/2.15.0/web-analytics/index.html index 709eca58d5..4ccd91890e 100644 --- a/docs/2.15.0/web-analytics/index.html +++ b/docs/2.15.0/web-analytics/index.html @@ -2,13 +2,13 @@ - -Add web analytics to your site | Richie - - + +Add web analytics to your site | Richie + + -
    Version: 2.15.0

    Add web analytics to your site

    Richie has native support to Google Analytics and Google Tag Manager Web Analytics solutions. +

    Version: 2.15.0

    Add web analytics to your site

    Richie has native support to Google Analytics and Google Tag Manager Web Analytics solutions. The purpose of this file is to explain how you can enable one of the supported Web Analytics providers and how you can extend Richie with an alternative solution.

    Google Analytics

    @@ -64,6 +64,6 @@

    +of src/frontend/js/utils/api/web-analytics/google_analytics.ts and change the src/frontend/js/utils/api/web-analytics/index.ts file to include that newer provider.

    \ No newline at end of file diff --git a/docs/2.15.1/accessibility-testing/index.html b/docs/2.15.1/accessibility-testing/index.html index 840b452d7f..00fe3a42f5 100644 --- a/docs/2.15.1/accessibility-testing/index.html +++ b/docs/2.15.1/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.15.1

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.15.1

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems in any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.15.1/api/course-run-synchronization-api/index.html b/docs/2.15.1/api/course-run-synchronization-api/index.html index 444da077bb..7b3ec5cd36 100644 --- a/docs/2.15.1/api/course-run-synchronization-api/index.html +++ b/docs/2.15.1/api/course-run-synchronization-api/index.html @@ -2,10 +2,10 @@ - -Course run synchronization API | Richie - - + +Course run synchronization API | Richie + +
    Version: 2.15.1

    Course run synchronization API

    API endpoint allowing remote systems to synchronize their course runs with a Richie instance.

    @@ -52,6 +52,6 @@

    +
    \ No newline at end of file diff --git a/docs/2.15.1/building-the-frontend/index.html b/docs/2.15.1/building-the-frontend/index.html index 0f4bc643ee..23324659f5 100644 --- a/docs/2.15.1/building-the-frontend/index.html +++ b/docs/2.15.1/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.15.1

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.15.1

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.15.1/contributing-guide/index.html b/docs/2.15.1/contributing-guide/index.html index 836dc40f77..bfb8a0bf59 100644 --- a/docs/2.15.1/contributing-guide/index.html +++ b/docs/2.15.1/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.15.1

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.15.1

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.15.1/cookiecutter/index.html b/docs/2.15.1/cookiecutter/index.html index 86f126d12d..2447c8eed3 100644 --- a/docs/2.15.1/cookiecutter/index.html +++ b/docs/2.15.1/cookiecutter/index.html @@ -2,13 +2,13 @@ - -Start your own site | Richie - - + +Start your own site | Richie + + -
    Version: 2.15.1

    Start your own site

    We use Cookiecutter to help you +

    Version: 2.15.1

    Start your own site

    We use Cookiecutter to help you set up a production-ready learning portal website based on Richie in seconds.

    Run Cookiecutter

    @@ -68,6 +68,6 @@

    cookiecutter --overwrite-if-exists gh:openfun/richie --directory=cookiecutter

    Help us improve this project

    After starting your project, please submit an issue let us know how it went and -what other features we should add to make it better.

    +what other features we should add to make it better.

    \ No newline at end of file diff --git a/docs/2.15.1/css-guidelines/index.html b/docs/2.15.1/css-guidelines/index.html index 72664718e1..17e128cd46 100644 --- a/docs/2.15.1/css-guidelines/index.html +++ b/docs/2.15.1/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.15.1

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.15.1

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.15.1/discover/index.html b/docs/2.15.1/discover/index.html index 4ef088c426..12b3da6764 100644 --- a/docs/2.15.1/discover/index.html +++ b/docs/2.15.1/discover/index.html @@ -2,13 +2,13 @@ - -Discover Richie | Richie - - + +Discover Richie | Richie + + -
    Version: 2.15.1

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online +

    Version: 2.15.1

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online courses and MOOCs.

    However, if you need to build a complete website with flexible content to aggregate your courses, in several languages and from different sources, you will soon need a CMS.

    @@ -51,6 +51,6 @@

    Start yo
  • override some css rules or rebuild the whole css with your own variables and customizations,
  • add any DjangoCMS plugin or feature,
  • add any Django third-party application.
  • -

    +
    \ No newline at end of file diff --git a/docs/2.15.1/displaying-connection-status/index.html b/docs/2.15.1/displaying-connection-status/index.html index fb891c3825..ffa0990cc1 100644 --- a/docs/2.15.1/displaying-connection-status/index.html +++ b/docs/2.15.1/displaying-connection-status/index.html @@ -2,10 +2,10 @@ - -Displaying OpenEdX connection status in Richie | Richie - - + +Displaying OpenEdX connection status in Richie | Richie + + +
    \ No newline at end of file diff --git a/docs/2.15.1/django-react-interop/index.html b/docs/2.15.1/django-react-interop/index.html index 365e95a4ce..10e9068216 100644 --- a/docs/2.15.1/django-react-interop/index.html +++ b/docs/2.15.1/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.15.1

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.15.1

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -64,6 +64,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.15.1/docker-development/index.html b/docs/2.15.1/docker-development/index.html index 9125de526c..99fc0eaed5 100644 --- a/docs/2.15.1/docker-development/index.html +++ b/docs/2.15.1/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.15.1

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.15.1

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.15.1/frontend-overrides/index.html b/docs/2.15.1/frontend-overrides/index.html index 8771b9c387..4a2cc0f8ff 100644 --- a/docs/2.15.1/frontend-overrides/index.html +++ b/docs/2.15.1/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.15.1

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.15.1

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.15.1/installation/index.html b/docs/2.15.1/installation/index.html index 59e06f8e5a..3d6c4ec70f 100644 --- a/docs/2.15.1/installation/index.html +++ b/docs/2.15.1/installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie for development | Richie - - + +Installing Richie for development | Richie + + -
    Version: 2.15.1

    Installing Richie for development

    Richie is a container-native application but can also be installed +

    +https://www.nau.edu.pt.

    \ No newline at end of file diff --git a/docs/2.15.1/internationalization/index.html b/docs/2.15.1/internationalization/index.html index 627f6d7b76..968154fcf5 100644 --- a/docs/2.15.1/internationalization/index.html +++ b/docs/2.15.1/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.15.1

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.15.1

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.15.1/joanie-connection/index.html b/docs/2.15.1/joanie-connection/index.html index 1bb13bdeea..c629d901a6 100644 --- a/docs/2.15.1/joanie-connection/index.html +++ b/docs/2.15.1/joanie-connection/index.html @@ -2,10 +2,10 @@ - -Joanie Connection | Richie - - + +Joanie Connection | Richie + +
    Version: 2.15.1

    Joanie Connection

    @@ -28,6 +28,6 @@

    Lifet

    To always have a valid access token, you have to configure properly its stale time according to the lifetime of the access token defined by your authentication server. For example, if your authentication server is using djangorestframework-simplejwt to generate the access token, -its lifetime is 5 minutes by default.

    +its lifetime is 5 minutes by default.

    \ No newline at end of file diff --git a/docs/2.15.1/lms-backends/index.html b/docs/2.15.1/lms-backends/index.html index e2c03e9822..b73168e6f9 100644 --- a/docs/2.15.1/lms-backends/index.html +++ b/docs/2.15.1/lms-backends/index.html @@ -2,10 +2,10 @@ - -Configuring LMS Backends | Richie - - + +Configuring LMS Backends | Richie + +
    Version: 2.15.1

    Configuring LMS Backends

    Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless @@ -115,6 +115,6 @@

    Technical

    If you encounter an issue with this documentation or the backends included in Richie, please open an issue on our repository.

    If you need a custom backend, you can submit a PR or -open an issue and we will consider adding it.

    +open an issue and we will consider adding it.

    \ No newline at end of file diff --git a/docs/2.15.1/lms-connection/index.html b/docs/2.15.1/lms-connection/index.html index 38c9c05720..d0248af853 100644 --- a/docs/2.15.1/lms-connection/index.html +++ b/docs/2.15.1/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with one or more LMS | Richie - - + +Connecting Richie with one or more LMS | Richie + + -
    Version: 2.15.1

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    +
    Version: 2.15.1

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    Richie can be connected to an LMS in several ways, ranging from SSO to a fully integrated seamless experience.

    As of today, each approach has been implemented for OpenEdX but the same could be done for @@ -63,6 +63,6 @@

    Development

    If you want to activate seamless enrollment locally for development, you will need to set up TLS domains for both Richie and OpenEdX. To do this, head over to our -guide on setting-up TLS connections for Richie and OpenEdX.

    +guide on setting-up TLS connections for Richie and OpenEdX.

    \ No newline at end of file diff --git a/docs/2.15.1/native-installation/index.html b/docs/2.15.1/native-installation/index.html index 5215dbbb74..aa36049e05 100644 --- a/docs/2.15.1/native-installation/index.html +++ b/docs/2.15.1/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.15.1

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.15.1

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native installation instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.15.1/synchronizing-course-runs/index.html b/docs/2.15.1/synchronizing-course-runs/index.html index b27685bf0d..83c8e39673 100644 --- a/docs/2.15.1/synchronizing-course-runs/index.html +++ b/docs/2.15.1/synchronizing-course-runs/index.html @@ -2,10 +2,10 @@ - -Synchronizing course runs between Richie and OpenEdX | Richie - - + +Synchronizing course runs between Richie and OpenEdX | Richie + +
    Version: 2.15.1

    Synchronizing course runs between Richie and OpenEdX

    Richie can receive automatic course runs updates on a dedicated API endpoint.

    @@ -51,6 +51,6 @@

    import hashlib
    import hmac
    import json

    from django.conf import settings

    from microsite_configuration import microsite
    import requests
    from xmodule.modulestore.django import modulestore


    def update_course(course_key, *args, **kwargs):
    """Synchronize an OpenEdX course, identified by its course key, with a Richie instance."""
    course = modulestore().get_course(course_key)
    edxapp_domain = microsite.get_value("site_domain", settings.LMS_BASE)

    data = {
    "resource_link": "https://{:s}/courses/{!s}/info".format(
    edxapp_domain, course_key
    ),
    "start": course.start and course.start.isoformat(),
    "end": course.end and course.end.isoformat(),
    "enrollment_start": course.enrollment_start and course.enrollment_start.isoformat(),
    "enrollment_end": course.enrollment_end and course.enrollment_end.isoformat(),
    "languages": [course.language or settings.LANGUAGE_CODE],
    }

    signature = hmac.new(
    setting.COURSE_HOOK["secret"].encode("utf-8"),
    msg=json.dumps(data).encode("utf-8"),
    digestmod=hashlib.sha256,
    ).hexdigest()

    response = requests.post(
    setting.COURSE_HOOK["url"],
    json=data,
    headers={"Authorization": "SIG-HMAC-SHA256 {:s}".format(signature)},
    )

    Thanks to the signal emitted in OpenEdX, this function can then be triggered each time a course is modified and published:

    -
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    +
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    \ No newline at end of file diff --git a/docs/2.15.1/tls-connection/index.html b/docs/2.15.1/tls-connection/index.html index 8680407217..78eb963fa3 100644 --- a/docs/2.15.1/tls-connection/index.html +++ b/docs/2.15.1/tls-connection/index.html @@ -2,10 +2,10 @@ - -Connecting Richie and OpenEdX over TLS for development | Richie - - + +Connecting Richie and OpenEdX over TLS for development | Richie + +
    Version: 2.15.1

    Connecting Richie and OpenEdX over TLS for development

    Purpose

    @@ -68,6 +68,6 @@

    $ make run-ssl

    Of course, you can still run apps without ssl by using:

    -
    $ make run
    +
    $ make run
    \ No newline at end of file diff --git a/docs/2.15.1/web-analytics/index.html b/docs/2.15.1/web-analytics/index.html index 30d16cfd70..a3fc27cc87 100644 --- a/docs/2.15.1/web-analytics/index.html +++ b/docs/2.15.1/web-analytics/index.html @@ -2,13 +2,13 @@ - -Add web analytics to your site | Richie - - + +Add web analytics to your site | Richie + + -
    Version: 2.15.1

    Add web analytics to your site

    Richie has native support to Google Analytics and Google Tag Manager Web Analytics solutions. +

    Version: 2.15.1

    Add web analytics to your site

    Richie has native support to Google Analytics and Google Tag Manager Web Analytics solutions. The purpose of this file is to explain how you can enable one of the supported Web Analytics providers and how you can extend Richie with an alternative solution.

    Google Analytics

    @@ -64,6 +64,6 @@

    +of src/frontend/js/utils/api/web-analytics/google_analytics.ts and change the src/frontend/js/utils/api/web-analytics/index.ts file to include that newer provider.

    \ No newline at end of file diff --git a/docs/2.16.0/accessibility-testing/index.html b/docs/2.16.0/accessibility-testing/index.html index b5f7c1e222..3f22840df2 100644 --- a/docs/2.16.0/accessibility-testing/index.html +++ b/docs/2.16.0/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.16.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.16.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems in any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.16.0/api/course-run-synchronization-api/index.html b/docs/2.16.0/api/course-run-synchronization-api/index.html index 5ef5329d6c..3e4e8196f0 100644 --- a/docs/2.16.0/api/course-run-synchronization-api/index.html +++ b/docs/2.16.0/api/course-run-synchronization-api/index.html @@ -2,10 +2,10 @@ - -Course run synchronization API | Richie - - + +Course run synchronization API | Richie + +
    Version: 2.16.0

    Course run synchronization API

    API endpoint allowing remote systems to synchronize their course runs with a Richie instance.

    @@ -52,6 +52,6 @@

    +
    \ No newline at end of file diff --git a/docs/2.16.0/building-the-frontend/index.html b/docs/2.16.0/building-the-frontend/index.html index b16b0d14ed..ef434eab5f 100644 --- a/docs/2.16.0/building-the-frontend/index.html +++ b/docs/2.16.0/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.16.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.16.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.16.0/contributing-guide/index.html b/docs/2.16.0/contributing-guide/index.html index 92b3b55354..b4b6219513 100644 --- a/docs/2.16.0/contributing-guide/index.html +++ b/docs/2.16.0/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.16.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.16.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.16.0/cookiecutter/index.html b/docs/2.16.0/cookiecutter/index.html index d0a757c29e..8008d3d924 100644 --- a/docs/2.16.0/cookiecutter/index.html +++ b/docs/2.16.0/cookiecutter/index.html @@ -2,13 +2,13 @@ - -Start your own site | Richie - - + +Start your own site | Richie + + -
    Version: 2.16.0

    Start your own site

    We use Cookiecutter to help you +

    Version: 2.16.0

    Start your own site

    We use Cookiecutter to help you set up a production-ready learning portal website based on Richie in seconds.

    Run Cookiecutter

    @@ -68,6 +68,6 @@

    cookiecutter --overwrite-if-exists gh:openfun/richie --directory=cookiecutter

    Help us improve this project

    After starting your project, please submit an issue let us know how it went and -what other features we should add to make it better.

    +what other features we should add to make it better.

    \ No newline at end of file diff --git a/docs/2.16.0/css-guidelines/index.html b/docs/2.16.0/css-guidelines/index.html index 554187768e..439dad234b 100644 --- a/docs/2.16.0/css-guidelines/index.html +++ b/docs/2.16.0/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.16.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.16.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.16.0/discover/index.html b/docs/2.16.0/discover/index.html index 14fbc5be8a..f372556a7e 100644 --- a/docs/2.16.0/discover/index.html +++ b/docs/2.16.0/discover/index.html @@ -2,13 +2,13 @@ - -Discover Richie | Richie - - + +Discover Richie | Richie + + -
    Version: 2.16.0

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online +

    Version: 2.16.0

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online courses and MOOCs.

    However, if you need to build a complete website with flexible content to aggregate your courses, in several languages and from different sources, you will soon need a CMS.

    @@ -51,6 +51,6 @@

    Start yo
  • override some css rules or rebuild the whole css with your own variables and customizations,
  • add any DjangoCMS plugin or feature,
  • add any Django third-party application.
  • -

    +
    \ No newline at end of file diff --git a/docs/2.16.0/displaying-connection-status/index.html b/docs/2.16.0/displaying-connection-status/index.html index 277edbf747..24c9eb296a 100644 --- a/docs/2.16.0/displaying-connection-status/index.html +++ b/docs/2.16.0/displaying-connection-status/index.html @@ -2,10 +2,10 @@ - -Displaying OpenEdX connection status in Richie | Richie - - + +Displaying OpenEdX connection status in Richie | Richie + + +
    \ No newline at end of file diff --git a/docs/2.16.0/django-react-interop/index.html b/docs/2.16.0/django-react-interop/index.html index 1efe09630e..992164e7dc 100644 --- a/docs/2.16.0/django-react-interop/index.html +++ b/docs/2.16.0/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.16.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.16.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -64,6 +64,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.16.0/docker-development/index.html b/docs/2.16.0/docker-development/index.html index f3a51f333b..3ae3aeaeeb 100644 --- a/docs/2.16.0/docker-development/index.html +++ b/docs/2.16.0/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.16.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.16.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.16.0/frontend-overrides/index.html b/docs/2.16.0/frontend-overrides/index.html index e1f964154a..5c29bd97ae 100644 --- a/docs/2.16.0/frontend-overrides/index.html +++ b/docs/2.16.0/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.16.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.16.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.16.0/installation/index.html b/docs/2.16.0/installation/index.html index 556f90f77a..b8f2f71cd4 100644 --- a/docs/2.16.0/installation/index.html +++ b/docs/2.16.0/installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie for development | Richie - - + +Installing Richie for development | Richie + + -
    Version: 2.16.0

    Installing Richie for development

    Richie is a container-native application but can also be installed +

    +https://www.nau.edu.pt.

    \ No newline at end of file diff --git a/docs/2.16.0/internationalization/index.html b/docs/2.16.0/internationalization/index.html index deac060f0b..95b125ad43 100644 --- a/docs/2.16.0/internationalization/index.html +++ b/docs/2.16.0/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.16.0

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.16.0

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.16.0/joanie-connection/index.html b/docs/2.16.0/joanie-connection/index.html index be2402573e..d3fcf0f3b5 100644 --- a/docs/2.16.0/joanie-connection/index.html +++ b/docs/2.16.0/joanie-connection/index.html @@ -2,10 +2,10 @@ - -Joanie Connection | Richie - - + +Joanie Connection | Richie + +
    Version: 2.16.0

    Joanie Connection

    @@ -28,6 +28,6 @@

    Lifet

    To always have a valid access token, you have to configure properly its stale time according to the lifetime of the access token defined by your authentication server. For example, if your authentication server is using djangorestframework-simplejwt to generate the access token, -its lifetime is 5 minutes by default.

    +its lifetime is 5 minutes by default.

    \ No newline at end of file diff --git a/docs/2.16.0/lms-backends/index.html b/docs/2.16.0/lms-backends/index.html index de9175a630..de9aaab962 100644 --- a/docs/2.16.0/lms-backends/index.html +++ b/docs/2.16.0/lms-backends/index.html @@ -2,10 +2,10 @@ - -Configuring LMS Backends | Richie - - + +Configuring LMS Backends | Richie + +
    Version: 2.16.0

    Configuring LMS Backends

    Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless @@ -115,6 +115,6 @@

    Technical

    If you encounter an issue with this documentation or the backends included in Richie, please open an issue on our repository.

    If you need a custom backend, you can submit a PR or -open an issue and we will consider adding it.

    +open an issue and we will consider adding it.

    \ No newline at end of file diff --git a/docs/2.16.0/lms-connection/index.html b/docs/2.16.0/lms-connection/index.html index 9fe3aea236..b2bd4893c0 100644 --- a/docs/2.16.0/lms-connection/index.html +++ b/docs/2.16.0/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with one or more LMS | Richie - - + +Connecting Richie with one or more LMS | Richie + + -
    Version: 2.16.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    +
    Version: 2.16.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    Richie can be connected to an LMS in several ways, ranging from SSO to a fully integrated seamless experience.

    As of today, each approach has been implemented for OpenEdX but the same could be done for @@ -63,6 +63,6 @@

    Development

    If you want to activate seamless enrollment locally for development, you will need to set up TLS domains for both Richie and OpenEdX. To do this, head over to our -guide on setting-up TLS connections for Richie and OpenEdX.

    +guide on setting-up TLS connections for Richie and OpenEdX.

    \ No newline at end of file diff --git a/docs/2.16.0/native-installation/index.html b/docs/2.16.0/native-installation/index.html index cc08ca73ca..d53ba6b4d2 100644 --- a/docs/2.16.0/native-installation/index.html +++ b/docs/2.16.0/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.16.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.16.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native installation instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.16.0/synchronizing-course-runs/index.html b/docs/2.16.0/synchronizing-course-runs/index.html index 9cf3bfff54..14a02de07d 100644 --- a/docs/2.16.0/synchronizing-course-runs/index.html +++ b/docs/2.16.0/synchronizing-course-runs/index.html @@ -2,10 +2,10 @@ - -Synchronizing course runs between Richie and OpenEdX | Richie - - + +Synchronizing course runs between Richie and OpenEdX | Richie + +
    Version: 2.16.0

    Synchronizing course runs between Richie and OpenEdX

    Richie can receive automatic course runs updates on a dedicated API endpoint.

    @@ -51,6 +51,6 @@

    import hashlib
    import hmac
    import json

    from django.conf import settings

    from microsite_configuration import microsite
    import requests
    from xmodule.modulestore.django import modulestore


    def update_course(course_key, *args, **kwargs):
    """Synchronize an OpenEdX course, identified by its course key, with a Richie instance."""
    course = modulestore().get_course(course_key)
    edxapp_domain = microsite.get_value("site_domain", settings.LMS_BASE)

    data = {
    "resource_link": "https://{:s}/courses/{!s}/info".format(
    edxapp_domain, course_key
    ),
    "start": course.start and course.start.isoformat(),
    "end": course.end and course.end.isoformat(),
    "enrollment_start": course.enrollment_start and course.enrollment_start.isoformat(),
    "enrollment_end": course.enrollment_end and course.enrollment_end.isoformat(),
    "languages": [course.language or settings.LANGUAGE_CODE],
    }

    signature = hmac.new(
    setting.COURSE_HOOK["secret"].encode("utf-8"),
    msg=json.dumps(data).encode("utf-8"),
    digestmod=hashlib.sha256,
    ).hexdigest()

    response = requests.post(
    setting.COURSE_HOOK["url"],
    json=data,
    headers={"Authorization": "SIG-HMAC-SHA256 {:s}".format(signature)},
    )

    Thanks to the signal emitted in OpenEdX, this function can then be triggered each time a course is modified and published:

    -
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    +
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    \ No newline at end of file diff --git a/docs/2.16.0/tls-connection/index.html b/docs/2.16.0/tls-connection/index.html index 50247886cd..a62430a3c7 100644 --- a/docs/2.16.0/tls-connection/index.html +++ b/docs/2.16.0/tls-connection/index.html @@ -2,10 +2,10 @@ - -Connecting Richie and OpenEdX over TLS for development | Richie - - + +Connecting Richie and OpenEdX over TLS for development | Richie + +
    Version: 2.16.0

    Connecting Richie and OpenEdX over TLS for development

    Purpose

    @@ -68,6 +68,6 @@

    $ make run-ssl

    Of course, you can still run apps without ssl by using:

    -
    $ make run
    +
    $ make run
    \ No newline at end of file diff --git a/docs/2.16.0/web-analytics/index.html b/docs/2.16.0/web-analytics/index.html index 842a95dd5e..3753f20dda 100644 --- a/docs/2.16.0/web-analytics/index.html +++ b/docs/2.16.0/web-analytics/index.html @@ -2,13 +2,13 @@ - -Add web analytics to your site | Richie - - + +Add web analytics to your site | Richie + + -
    Version: 2.16.0

    Add web analytics to your site

    Richie has native support to Google Analytics and Google Tag Manager Web Analytics solutions. +

    Version: 2.16.0

    Add web analytics to your site

    Richie has native support to Google Analytics and Google Tag Manager Web Analytics solutions. The purpose of this file is to explain how you can enable one of the supported Web Analytics providers and how you can extend Richie with an alternative solution.

    Google Analytics

    @@ -64,6 +64,6 @@

    +of src/frontend/js/utils/api/web-analytics/google_analytics.ts and change the src/frontend/js/utils/api/web-analytics/index.ts file to include that newer provider.

    \ No newline at end of file diff --git a/docs/2.17.0/accessibility-testing/index.html b/docs/2.17.0/accessibility-testing/index.html index 8980c996f7..2563917249 100644 --- a/docs/2.17.0/accessibility-testing/index.html +++ b/docs/2.17.0/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.17.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.17.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems in any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.17.0/api/course-run-synchronization-api/index.html b/docs/2.17.0/api/course-run-synchronization-api/index.html index 9d162ca192..a58e4bf89f 100644 --- a/docs/2.17.0/api/course-run-synchronization-api/index.html +++ b/docs/2.17.0/api/course-run-synchronization-api/index.html @@ -2,10 +2,10 @@ - -Course run synchronization API | Richie - - + +Course run synchronization API | Richie + +
    Version: 2.17.0

    Course run synchronization API

    API endpoint allowing remote systems to synchronize their course runs with a Richie instance.

    @@ -52,6 +52,6 @@

    +
    \ No newline at end of file diff --git a/docs/2.17.0/building-the-frontend/index.html b/docs/2.17.0/building-the-frontend/index.html index 66fdfebafc..5bf4f29029 100644 --- a/docs/2.17.0/building-the-frontend/index.html +++ b/docs/2.17.0/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.17.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.17.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.17.0/contributing-guide/index.html b/docs/2.17.0/contributing-guide/index.html index b7da23410d..163e6eabd5 100644 --- a/docs/2.17.0/contributing-guide/index.html +++ b/docs/2.17.0/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.17.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.17.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.17.0/cookiecutter/index.html b/docs/2.17.0/cookiecutter/index.html index 884e07d6a1..7dcfd27502 100644 --- a/docs/2.17.0/cookiecutter/index.html +++ b/docs/2.17.0/cookiecutter/index.html @@ -2,13 +2,13 @@ - -Start your own site | Richie - - + +Start your own site | Richie + + -
    Version: 2.17.0

    Start your own site

    We use Cookiecutter to help you +

    Version: 2.17.0

    Start your own site

    We use Cookiecutter to help you set up a production-ready learning portal website based on Richie in seconds.

    Run Cookiecutter

    @@ -73,6 +73,6 @@

    cookiecutter --overwrite-if-exists gh:openfun/richie --directory=cookiecutter

    Help us improve this project

    After starting your project, please submit an issue let us know how it went and -what other features we should add to make it better.

    +what other features we should add to make it better.

    \ No newline at end of file diff --git a/docs/2.17.0/css-guidelines/index.html b/docs/2.17.0/css-guidelines/index.html index 74aef91ee1..604f78047a 100644 --- a/docs/2.17.0/css-guidelines/index.html +++ b/docs/2.17.0/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.17.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.17.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.17.0/discover/index.html b/docs/2.17.0/discover/index.html index d5f970e507..4aa4a1c5fc 100644 --- a/docs/2.17.0/discover/index.html +++ b/docs/2.17.0/discover/index.html @@ -2,13 +2,13 @@ - -Discover Richie | Richie - - + +Discover Richie | Richie + + -
    Version: 2.17.0

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online +

    Version: 2.17.0

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online courses and MOOCs.

    However, if you need to build a complete website with flexible content to aggregate your courses, in several languages and from different sources, you will soon need a CMS.

    @@ -51,6 +51,6 @@

    Start yo
  • override some css rules or rebuild the whole css with your own variables and customizations,
  • add any DjangoCMS plugin or feature,
  • add any Django third-party application.
  • -

    +
    \ No newline at end of file diff --git a/docs/2.17.0/displaying-connection-status/index.html b/docs/2.17.0/displaying-connection-status/index.html index fac9d980bc..4ac9ed2906 100644 --- a/docs/2.17.0/displaying-connection-status/index.html +++ b/docs/2.17.0/displaying-connection-status/index.html @@ -2,10 +2,10 @@ - -Displaying OpenEdX connection status in Richie | Richie - - + +Displaying OpenEdX connection status in Richie | Richie + + +
    \ No newline at end of file diff --git a/docs/2.17.0/django-react-interop/index.html b/docs/2.17.0/django-react-interop/index.html index c0c2759ee6..d02ae29212 100644 --- a/docs/2.17.0/django-react-interop/index.html +++ b/docs/2.17.0/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.17.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.17.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -64,6 +64,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.17.0/docker-development/index.html b/docs/2.17.0/docker-development/index.html index 20243713e4..028c4bff05 100644 --- a/docs/2.17.0/docker-development/index.html +++ b/docs/2.17.0/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.17.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.17.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.17.0/filters-customization/index.html b/docs/2.17.0/filters-customization/index.html index fb43420997..f36a2c572a 100644 --- a/docs/2.17.0/filters-customization/index.html +++ b/docs/2.17.0/filters-customization/index.html @@ -2,13 +2,13 @@ - -Customizing search filters | Richie - - + +Customizing search filters | Richie + + -
    Version: 2.17.0

    Customizing search filters

    You may want to customize the filters on the left side bar of the search page.

    +
    Version: 2.17.0

    Customizing search filters

    You may want to customize the filters on the left side bar of the search page.

    Richie makes it easy to choose which filters you want to display among the existing filters and in which order. You can also configure the existing filters to change their title or the way they behave. Lastly, you can completely override a filter or create your own custom filter @@ -88,6 +88,6 @@

    opening an issue!

    +opening an issue!

    \ No newline at end of file diff --git a/docs/2.17.0/frontend-overrides/index.html b/docs/2.17.0/frontend-overrides/index.html index 185ef88f9a..e418653074 100644 --- a/docs/2.17.0/frontend-overrides/index.html +++ b/docs/2.17.0/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.17.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.17.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.17.0/installation/index.html b/docs/2.17.0/installation/index.html index 28cf893638..0aa80ccf33 100644 --- a/docs/2.17.0/installation/index.html +++ b/docs/2.17.0/installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie for development | Richie - - + +Installing Richie for development | Richie + + -
    Version: 2.17.0

    Installing Richie for development

    Richie is a container-native application but can also be installed +

    +https://www.nau.edu.pt.

    \ No newline at end of file diff --git a/docs/2.17.0/internationalization/index.html b/docs/2.17.0/internationalization/index.html index 24a9a91fd6..5300ce2e35 100644 --- a/docs/2.17.0/internationalization/index.html +++ b/docs/2.17.0/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.17.0

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.17.0

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.17.0/joanie-connection/index.html b/docs/2.17.0/joanie-connection/index.html index 6572c22c13..e9fcdb51f8 100644 --- a/docs/2.17.0/joanie-connection/index.html +++ b/docs/2.17.0/joanie-connection/index.html @@ -2,10 +2,10 @@ - -Joanie Connection | Richie - - + +Joanie Connection | Richie + +
    Version: 2.17.0

    Joanie Connection

    @@ -28,6 +28,6 @@

    Lifet

    To always have a valid access token, you have to configure properly its stale time according to the lifetime of the access token defined by your authentication server. For example, if your authentication server is using djangorestframework-simplejwt to generate the access token, -its lifetime is 5 minutes by default.

    +its lifetime is 5 minutes by default.

    \ No newline at end of file diff --git a/docs/2.17.0/lms-backends/index.html b/docs/2.17.0/lms-backends/index.html index 6e5bee82af..8a282a85a0 100644 --- a/docs/2.17.0/lms-backends/index.html +++ b/docs/2.17.0/lms-backends/index.html @@ -2,10 +2,10 @@ - -Configuring LMS Backends | Richie - - + +Configuring LMS Backends | Richie + +
    Version: 2.17.0

    Configuring LMS Backends

    Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless @@ -115,6 +115,6 @@

    Technical

    If you encounter an issue with this documentation or the backends included in Richie, please open an issue on our repository.

    If you need a custom backend, you can submit a PR or -open an issue and we will consider adding it.

    +open an issue and we will consider adding it.

    \ No newline at end of file diff --git a/docs/2.17.0/lms-connection/index.html b/docs/2.17.0/lms-connection/index.html index 341210c720..bbdc5bd3cd 100644 --- a/docs/2.17.0/lms-connection/index.html +++ b/docs/2.17.0/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with one or more LMS | Richie - - + +Connecting Richie with one or more LMS | Richie + + -
    Version: 2.17.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    +
    Version: 2.17.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    Richie can be connected to an LMS in several ways, ranging from SSO to a fully integrated seamless experience.

    As of today, each approach has been implemented for OpenEdX but the same could be done for @@ -63,6 +63,6 @@

    Development

    If you want to activate seamless enrollment locally for development, you will need to set up TLS domains for both Richie and OpenEdX. To do this, head over to our -guide on setting-up TLS connections for Richie and OpenEdX.

    +guide on setting-up TLS connections for Richie and OpenEdX.

    \ No newline at end of file diff --git a/docs/2.17.0/native-installation/index.html b/docs/2.17.0/native-installation/index.html index 803e5380df..a89ecada5d 100644 --- a/docs/2.17.0/native-installation/index.html +++ b/docs/2.17.0/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.17.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.17.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native installation instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.17.0/synchronizing-course-runs/index.html b/docs/2.17.0/synchronizing-course-runs/index.html index 0eda1bdd80..1901acfa41 100644 --- a/docs/2.17.0/synchronizing-course-runs/index.html +++ b/docs/2.17.0/synchronizing-course-runs/index.html @@ -2,10 +2,10 @@ - -Synchronizing course runs between Richie and OpenEdX | Richie - - + +Synchronizing course runs between Richie and OpenEdX | Richie + +
    Version: 2.17.0

    Synchronizing course runs between Richie and OpenEdX

    Richie can receive automatic course runs updates on a dedicated API endpoint.

    @@ -51,6 +51,6 @@

    import hashlib
    import hmac
    import json

    from django.conf import settings

    from microsite_configuration import microsite
    import requests
    from xmodule.modulestore.django import modulestore


    def update_course(course_key, *args, **kwargs):
    """Synchronize an OpenEdX course, identified by its course key, with a Richie instance."""
    course = modulestore().get_course(course_key)
    edxapp_domain = microsite.get_value("site_domain", settings.LMS_BASE)

    data = {
    "resource_link": "https://{:s}/courses/{!s}/info".format(
    edxapp_domain, course_key
    ),
    "start": course.start and course.start.isoformat(),
    "end": course.end and course.end.isoformat(),
    "enrollment_start": course.enrollment_start and course.enrollment_start.isoformat(),
    "enrollment_end": course.enrollment_end and course.enrollment_end.isoformat(),
    "languages": [course.language or settings.LANGUAGE_CODE],
    }

    signature = hmac.new(
    setting.COURSE_HOOK["secret"].encode("utf-8"),
    msg=json.dumps(data).encode("utf-8"),
    digestmod=hashlib.sha256,
    ).hexdigest()

    response = requests.post(
    setting.COURSE_HOOK["url"],
    json=data,
    headers={"Authorization": "SIG-HMAC-SHA256 {:s}".format(signature)},
    )

    Thanks to the signal emitted in OpenEdX, this function can then be triggered each time a course is modified and published:

    -
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    +
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    \ No newline at end of file diff --git a/docs/2.17.0/tls-connection/index.html b/docs/2.17.0/tls-connection/index.html index 4eb88df70c..23f6150c34 100644 --- a/docs/2.17.0/tls-connection/index.html +++ b/docs/2.17.0/tls-connection/index.html @@ -2,10 +2,10 @@ - -Connecting Richie and OpenEdX over TLS for development | Richie - - + +Connecting Richie and OpenEdX over TLS for development | Richie + +
    Version: 2.17.0

    Connecting Richie and OpenEdX over TLS for development

    Purpose

    @@ -68,6 +68,6 @@

    $ make run-ssl

    Of course, you can still run apps without ssl by using:

    -
    $ make run
    +
    $ make run
    \ No newline at end of file diff --git a/docs/2.17.0/web-analytics/index.html b/docs/2.17.0/web-analytics/index.html index e3ce94bdde..a18d0f305d 100644 --- a/docs/2.17.0/web-analytics/index.html +++ b/docs/2.17.0/web-analytics/index.html @@ -2,13 +2,13 @@ - -Add web analytics to your site | Richie - - + +Add web analytics to your site | Richie + + -
    Version: 2.17.0

    Add web analytics to your site

    Richie has native support to Google Analytics and Google Tag Manager Web Analytics solutions. +

    Version: 2.17.0

    Add web analytics to your site

    Richie has native support to Google Analytics and Google Tag Manager Web Analytics solutions. The purpose of this file is to explain how you can enable one of the supported Web Analytics providers and how you can extend Richie with an alternative solution.

    Google Analytics

    @@ -64,6 +64,6 @@

    +of src/frontend/js/utils/api/web-analytics/google_analytics.ts and change the src/frontend/js/utils/api/web-analytics/index.ts file to include that newer provider.

    \ No newline at end of file diff --git a/docs/2.18.0/accessibility-testing/index.html b/docs/2.18.0/accessibility-testing/index.html index 5aede4c710..ecab4361e0 100644 --- a/docs/2.18.0/accessibility-testing/index.html +++ b/docs/2.18.0/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.18.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.18.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems in any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.18.0/api/course-run-synchronization-api/index.html b/docs/2.18.0/api/course-run-synchronization-api/index.html index cb9c4ffb4c..fedc1af281 100644 --- a/docs/2.18.0/api/course-run-synchronization-api/index.html +++ b/docs/2.18.0/api/course-run-synchronization-api/index.html @@ -2,10 +2,10 @@ - -Course run synchronization API | Richie - - + +Course run synchronization API | Richie + +
    Version: 2.18.0

    Course run synchronization API

    API endpoint allowing remote systems to synchronize their course runs with a Richie instance.

    @@ -52,6 +52,6 @@

    +
    \ No newline at end of file diff --git a/docs/2.18.0/building-the-frontend/index.html b/docs/2.18.0/building-the-frontend/index.html index f2431ec72a..85211f24df 100644 --- a/docs/2.18.0/building-the-frontend/index.html +++ b/docs/2.18.0/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.18.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.18.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.18.0/contributing-guide/index.html b/docs/2.18.0/contributing-guide/index.html index bbfad1dd21..49dc5a14a1 100644 --- a/docs/2.18.0/contributing-guide/index.html +++ b/docs/2.18.0/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.18.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.18.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.18.0/cookiecutter/index.html b/docs/2.18.0/cookiecutter/index.html index 1fa85d6185..1ee1e8983c 100644 --- a/docs/2.18.0/cookiecutter/index.html +++ b/docs/2.18.0/cookiecutter/index.html @@ -2,13 +2,13 @@ - -Start your own site | Richie - - + +Start your own site | Richie + + -
    Version: 2.18.0

    Start your own site

    We use Cookiecutter to help you +

    Version: 2.18.0

    Start your own site

    We use Cookiecutter to help you set up a production-ready learning portal website based on Richie in seconds.

    Run Cookiecutter

    @@ -73,6 +73,6 @@

    cookiecutter --overwrite-if-exists gh:openfun/richie --directory=cookiecutter

    Help us improve this project

    After starting your project, please submit an issue let us know how it went and -what other features we should add to make it better.

    +what other features we should add to make it better.

    \ No newline at end of file diff --git a/docs/2.18.0/css-guidelines/index.html b/docs/2.18.0/css-guidelines/index.html index 5957cadf99..e7f99c0526 100644 --- a/docs/2.18.0/css-guidelines/index.html +++ b/docs/2.18.0/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.18.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.18.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.18.0/discover/index.html b/docs/2.18.0/discover/index.html index 2aeb2de31c..c2a903420e 100644 --- a/docs/2.18.0/discover/index.html +++ b/docs/2.18.0/discover/index.html @@ -2,13 +2,13 @@ - -Discover Richie | Richie - - + +Discover Richie | Richie + + -
    Version: 2.18.0

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online +

    Version: 2.18.0

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online courses and MOOCs.

    However, if you need to build a complete website with flexible content to aggregate your courses, in several languages and from different sources, you will soon need a CMS.

    @@ -51,6 +51,6 @@

    Start yo
  • override some css rules or rebuild the whole css with your own variables and customizations,
  • add any DjangoCMS plugin or feature,
  • add any Django third-party application.
  • -

    +
    \ No newline at end of file diff --git a/docs/2.18.0/displaying-connection-status/index.html b/docs/2.18.0/displaying-connection-status/index.html index 04df07ea18..62dfab96be 100644 --- a/docs/2.18.0/displaying-connection-status/index.html +++ b/docs/2.18.0/displaying-connection-status/index.html @@ -2,10 +2,10 @@ - -Displaying OpenEdX connection status in Richie | Richie - - + +Displaying OpenEdX connection status in Richie | Richie + + +
    \ No newline at end of file diff --git a/docs/2.18.0/django-react-interop/index.html b/docs/2.18.0/django-react-interop/index.html index d9657cf9f0..40ab7bfcae 100644 --- a/docs/2.18.0/django-react-interop/index.html +++ b/docs/2.18.0/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.18.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.18.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -64,6 +64,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.18.0/docker-development/index.html b/docs/2.18.0/docker-development/index.html index c0391c2d38..7bb9d54d3f 100644 --- a/docs/2.18.0/docker-development/index.html +++ b/docs/2.18.0/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.18.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.18.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.18.0/filters-customization/index.html b/docs/2.18.0/filters-customization/index.html index 9c9a484ad7..b62c9ec21e 100644 --- a/docs/2.18.0/filters-customization/index.html +++ b/docs/2.18.0/filters-customization/index.html @@ -2,13 +2,13 @@ - -Customizing search filters | Richie - - + +Customizing search filters | Richie + + -
    Version: 2.18.0

    Customizing search filters

    You may want to customize the filters on the left side bar of the search page.

    +
    Version: 2.18.0

    Customizing search filters

    You may want to customize the filters on the left side bar of the search page.

    Richie makes it easy to choose which filters you want to display among the existing filters and in which order. You can also configure the existing filters to change their title or the way they behave. Lastly, you can completely override a filter or create your own custom filter @@ -88,6 +88,6 @@

    opening an issue!

    +opening an issue!

    \ No newline at end of file diff --git a/docs/2.18.0/frontend-overrides/index.html b/docs/2.18.0/frontend-overrides/index.html index 23280d40aa..acc03da7fd 100644 --- a/docs/2.18.0/frontend-overrides/index.html +++ b/docs/2.18.0/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.18.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.18.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.18.0/installation/index.html b/docs/2.18.0/installation/index.html index 5d9d0872ea..85785ffcef 100644 --- a/docs/2.18.0/installation/index.html +++ b/docs/2.18.0/installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie for development | Richie - - + +Installing Richie for development | Richie + + -
    Version: 2.18.0

    Installing Richie for development

    Richie is a container-native application but can also be installed +

    +https://www.nau.edu.pt.

    \ No newline at end of file diff --git a/docs/2.18.0/internationalization/index.html b/docs/2.18.0/internationalization/index.html index 97f338b6bb..f22193296b 100644 --- a/docs/2.18.0/internationalization/index.html +++ b/docs/2.18.0/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.18.0

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.18.0

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.18.0/joanie-connection/index.html b/docs/2.18.0/joanie-connection/index.html index 0e5d975edd..29486ab5fa 100644 --- a/docs/2.18.0/joanie-connection/index.html +++ b/docs/2.18.0/joanie-connection/index.html @@ -2,10 +2,10 @@ - -Joanie Connection | Richie - - + +Joanie Connection | Richie + +
    Version: 2.18.0

    Joanie Connection

    @@ -31,6 +31,6 @@

    Lifet

    To always have a valid access token, you have to configure properly its stale time according to the lifetime of the access token defined by your authentication server. For example, if your authentication server is using djangorestframework-simplejwt to generate the access token, -its lifetime is 5 minutes by default.

    +its lifetime is 5 minutes by default.

    \ No newline at end of file diff --git a/docs/2.18.0/lms-backends/index.html b/docs/2.18.0/lms-backends/index.html index 6d97431fa8..d50933b58e 100644 --- a/docs/2.18.0/lms-backends/index.html +++ b/docs/2.18.0/lms-backends/index.html @@ -2,10 +2,10 @@ - -Configuring LMS Backends | Richie - - + +Configuring LMS Backends | Richie + +
    Version: 2.18.0

    Configuring LMS Backends

    Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless @@ -115,6 +115,6 @@

    Technical

    If you encounter an issue with this documentation or the backends included in Richie, please open an issue on our repository.

    If you need a custom backend, you can submit a PR or -open an issue and we will consider adding it.

    +open an issue and we will consider adding it.

    \ No newline at end of file diff --git a/docs/2.18.0/lms-connection/index.html b/docs/2.18.0/lms-connection/index.html index a322980551..499422ebf6 100644 --- a/docs/2.18.0/lms-connection/index.html +++ b/docs/2.18.0/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with one or more LMS | Richie - - + +Connecting Richie with one or more LMS | Richie + + -
    Version: 2.18.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    +
    Version: 2.18.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    Richie can be connected to an LMS in several ways, ranging from SSO to a fully integrated seamless experience.

    As of today, each approach has been implemented for OpenEdX but the same could be done for @@ -63,6 +63,6 @@

    Development

    If you want to activate seamless enrollment locally for development, you will need to set up TLS domains for both Richie and OpenEdX. To do this, head over to our -guide on setting-up TLS connections for Richie and OpenEdX.

    +guide on setting-up TLS connections for Richie and OpenEdX.

    \ No newline at end of file diff --git a/docs/2.18.0/native-installation/index.html b/docs/2.18.0/native-installation/index.html index ad435660de..7383cfd5ec 100644 --- a/docs/2.18.0/native-installation/index.html +++ b/docs/2.18.0/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.18.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.18.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native installation instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.18.0/synchronizing-course-runs/index.html b/docs/2.18.0/synchronizing-course-runs/index.html index 429f3e6e3a..426d35d938 100644 --- a/docs/2.18.0/synchronizing-course-runs/index.html +++ b/docs/2.18.0/synchronizing-course-runs/index.html @@ -2,10 +2,10 @@ - -Synchronizing course runs between Richie and OpenEdX | Richie - - + +Synchronizing course runs between Richie and OpenEdX | Richie + +
    Version: 2.18.0

    Synchronizing course runs between Richie and OpenEdX

    Richie can receive automatic course runs updates on a dedicated API endpoint.

    @@ -51,6 +51,6 @@

    import hashlib
    import hmac
    import json

    from django.conf import settings

    from microsite_configuration import microsite
    import requests
    from xmodule.modulestore.django import modulestore


    def update_course(course_key, *args, **kwargs):
    """Synchronize an OpenEdX course, identified by its course key, with a Richie instance."""
    course = modulestore().get_course(course_key)
    edxapp_domain = microsite.get_value("site_domain", settings.LMS_BASE)

    data = {
    "resource_link": "https://{:s}/courses/{!s}/info".format(
    edxapp_domain, course_key
    ),
    "start": course.start and course.start.isoformat(),
    "end": course.end and course.end.isoformat(),
    "enrollment_start": course.enrollment_start and course.enrollment_start.isoformat(),
    "enrollment_end": course.enrollment_end and course.enrollment_end.isoformat(),
    "languages": [course.language or settings.LANGUAGE_CODE],
    }

    signature = hmac.new(
    setting.COURSE_HOOK["secret"].encode("utf-8"),
    msg=json.dumps(data).encode("utf-8"),
    digestmod=hashlib.sha256,
    ).hexdigest()

    response = requests.post(
    setting.COURSE_HOOK["url"],
    json=data,
    headers={"Authorization": "SIG-HMAC-SHA256 {:s}".format(signature)},
    )

    Thanks to the signal emitted in OpenEdX, this function can then be triggered each time a course is modified and published:

    -
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    +
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    \ No newline at end of file diff --git a/docs/2.18.0/tls-connection/index.html b/docs/2.18.0/tls-connection/index.html index a4ffa900d2..92c1acf1ac 100644 --- a/docs/2.18.0/tls-connection/index.html +++ b/docs/2.18.0/tls-connection/index.html @@ -2,10 +2,10 @@ - -Connecting Richie and OpenEdX over TLS for development | Richie - - + +Connecting Richie and OpenEdX over TLS for development | Richie + +
    Version: 2.18.0

    Connecting Richie and OpenEdX over TLS for development

    Purpose

    @@ -68,6 +68,6 @@

    $ make run-ssl

    Of course, you can still run apps without ssl by using:

    -
    $ make run
    +
    $ make run
    \ No newline at end of file diff --git a/docs/2.18.0/web-analytics/index.html b/docs/2.18.0/web-analytics/index.html index 8921ef8f26..305709e3ed 100644 --- a/docs/2.18.0/web-analytics/index.html +++ b/docs/2.18.0/web-analytics/index.html @@ -2,13 +2,13 @@ - -Add web analytics to your site | Richie - - + +Add web analytics to your site | Richie + + -
    Version: 2.18.0

    Add web analytics to your site

    Richie has native support to Google Analytics and Google Tag Manager Web Analytics solutions. +

    Version: 2.18.0

    Add web analytics to your site

    Richie has native support to Google Analytics and Google Tag Manager Web Analytics solutions. The purpose of this file is to explain how you can enable one of the supported Web Analytics providers and how you can extend Richie with an alternative solution.

    Google Analytics

    @@ -64,6 +64,6 @@

    +of src/frontend/js/utils/api/web-analytics/google_analytics.ts and change the src/frontend/js/utils/api/web-analytics/index.ts file to include that newer provider.

    \ No newline at end of file diff --git a/docs/2.19.0/accessibility-testing/index.html b/docs/2.19.0/accessibility-testing/index.html index 78dd44a34c..1fdc55b3cc 100644 --- a/docs/2.19.0/accessibility-testing/index.html +++ b/docs/2.19.0/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.19.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.19.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems in any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.19.0/api/course-run-synchronization-api/index.html b/docs/2.19.0/api/course-run-synchronization-api/index.html index c6edb4e13d..9e4aaf756d 100644 --- a/docs/2.19.0/api/course-run-synchronization-api/index.html +++ b/docs/2.19.0/api/course-run-synchronization-api/index.html @@ -2,10 +2,10 @@ - -Course run synchronization API | Richie - - + +Course run synchronization API | Richie + +
    Version: 2.19.0

    Course run synchronization API

    API endpoint allowing remote systems to synchronize their course runs with a Richie instance.

    @@ -52,6 +52,6 @@

    +
    \ No newline at end of file diff --git a/docs/2.19.0/building-the-frontend/index.html b/docs/2.19.0/building-the-frontend/index.html index 14a6cd02d6..6b9a8568c3 100644 --- a/docs/2.19.0/building-the-frontend/index.html +++ b/docs/2.19.0/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.19.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.19.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.19.0/contributing-guide/index.html b/docs/2.19.0/contributing-guide/index.html index cc3592cfdd..22a2314e56 100644 --- a/docs/2.19.0/contributing-guide/index.html +++ b/docs/2.19.0/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.19.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.19.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.19.0/cookiecutter/index.html b/docs/2.19.0/cookiecutter/index.html index c14be4e2d5..f6fffd8cff 100644 --- a/docs/2.19.0/cookiecutter/index.html +++ b/docs/2.19.0/cookiecutter/index.html @@ -2,13 +2,13 @@ - -Start your own site | Richie - - + +Start your own site | Richie + + -
    Version: 2.19.0

    Start your own site

    We use Cookiecutter to help you +

    Version: 2.19.0

    Start your own site

    We use Cookiecutter to help you set up a production-ready learning portal website based on Richie in seconds.

    Run Cookiecutter

    @@ -73,6 +73,6 @@

    cookiecutter --overwrite-if-exists gh:openfun/richie --directory=cookiecutter

    Help us improve this project

    After starting your project, please submit an issue let us know how it went and -what other features we should add to make it better.

    +what other features we should add to make it better.

    \ No newline at end of file diff --git a/docs/2.19.0/css-guidelines/index.html b/docs/2.19.0/css-guidelines/index.html index 46b02f8a7b..47e8e325d8 100644 --- a/docs/2.19.0/css-guidelines/index.html +++ b/docs/2.19.0/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.19.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.19.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.19.0/discover/index.html b/docs/2.19.0/discover/index.html index 7a557a7aea..916bd71d9b 100644 --- a/docs/2.19.0/discover/index.html +++ b/docs/2.19.0/discover/index.html @@ -2,13 +2,13 @@ - -Discover Richie | Richie - - + +Discover Richie | Richie + + -
    Version: 2.19.0

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online +

    Version: 2.19.0

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online courses and MOOCs.

    However, if you need to build a complete website with flexible content to aggregate your courses, in several languages and from different sources, you will soon need a CMS.

    @@ -51,6 +51,6 @@

    Start yo
  • override some css rules or rebuild the whole css with your own variables and customizations,
  • add any DjangoCMS plugin or feature,
  • add any Django third-party application.
  • -

    +
    \ No newline at end of file diff --git a/docs/2.19.0/displaying-connection-status/index.html b/docs/2.19.0/displaying-connection-status/index.html index f14fa5485b..91387152ed 100644 --- a/docs/2.19.0/displaying-connection-status/index.html +++ b/docs/2.19.0/displaying-connection-status/index.html @@ -2,10 +2,10 @@ - -Displaying OpenEdX connection status in Richie | Richie - - + +Displaying OpenEdX connection status in Richie | Richie + + +
    \ No newline at end of file diff --git a/docs/2.19.0/django-react-interop/index.html b/docs/2.19.0/django-react-interop/index.html index 399957dc86..d08ac54e00 100644 --- a/docs/2.19.0/django-react-interop/index.html +++ b/docs/2.19.0/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.19.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.19.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -64,6 +64,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.19.0/docker-development/index.html b/docs/2.19.0/docker-development/index.html index 7b46849cce..10abee0505 100644 --- a/docs/2.19.0/docker-development/index.html +++ b/docs/2.19.0/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.19.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.19.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.19.0/filters-customization/index.html b/docs/2.19.0/filters-customization/index.html index 89cc8b3a6d..b78f9b67a5 100644 --- a/docs/2.19.0/filters-customization/index.html +++ b/docs/2.19.0/filters-customization/index.html @@ -2,13 +2,13 @@ - -Customizing search filters | Richie - - + +Customizing search filters | Richie + + -
    Version: 2.19.0

    Customizing search filters

    You may want to customize the filters on the left side bar of the search page.

    +
    Version: 2.19.0

    Customizing search filters

    You may want to customize the filters on the left side bar of the search page.

    Richie makes it easy to choose which filters you want to display among the existing filters and in which order. You can also configure the existing filters to change their title or the way they behave. Lastly, you can completely override a filter or create your own custom filter @@ -88,6 +88,6 @@

    opening an issue!

    +opening an issue!

    \ No newline at end of file diff --git a/docs/2.19.0/frontend-overrides/index.html b/docs/2.19.0/frontend-overrides/index.html index bb2d7ca6fb..6877b0ec9f 100644 --- a/docs/2.19.0/frontend-overrides/index.html +++ b/docs/2.19.0/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.19.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.19.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.19.0/installation/index.html b/docs/2.19.0/installation/index.html index 99586ab2de..d2828042f3 100644 --- a/docs/2.19.0/installation/index.html +++ b/docs/2.19.0/installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie for development | Richie - - + +Installing Richie for development | Richie + + -
    Version: 2.19.0

    Installing Richie for development

    Richie is a container-native application but can also be installed +

    +https://www.nau.edu.pt.

    \ No newline at end of file diff --git a/docs/2.19.0/internationalization/index.html b/docs/2.19.0/internationalization/index.html index 3fdbaa1ffd..32a5f5b03d 100644 --- a/docs/2.19.0/internationalization/index.html +++ b/docs/2.19.0/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.19.0

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.19.0

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.19.0/joanie-connection/index.html b/docs/2.19.0/joanie-connection/index.html index 82b76d930a..82a911bcd7 100644 --- a/docs/2.19.0/joanie-connection/index.html +++ b/docs/2.19.0/joanie-connection/index.html @@ -2,10 +2,10 @@ - -Joanie Connection | Richie - - + +Joanie Connection | Richie + +
    Version: 2.19.0

    Joanie Connection

    Joanie delivers an API able to manage course @@ -90,6 +90,6 @@

    Lifet its lifetime is 5 minutes by default.

    Technical support

    If you encounter an issue with this documentation, please -open an issue on our repository.

    +open an issue on our repository.

    \ No newline at end of file diff --git a/docs/2.19.0/lms-backends/index.html b/docs/2.19.0/lms-backends/index.html index 940b1bee65..4bca7cb880 100644 --- a/docs/2.19.0/lms-backends/index.html +++ b/docs/2.19.0/lms-backends/index.html @@ -2,10 +2,10 @@ - -Configuring LMS Backends | Richie - - + +Configuring LMS Backends | Richie + +
    Version: 2.19.0

    Configuring LMS Backends

    Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless @@ -115,6 +115,6 @@

    Technical

    If you encounter an issue with this documentation or the backends included in Richie, please open an issue on our repository.

    If you need a custom backend, you can submit a PR or -open an issue and we will consider adding it.

    +open an issue and we will consider adding it.

    \ No newline at end of file diff --git a/docs/2.19.0/lms-connection/index.html b/docs/2.19.0/lms-connection/index.html index 40d3cc0bf2..8c43976216 100644 --- a/docs/2.19.0/lms-connection/index.html +++ b/docs/2.19.0/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with one or more LMS | Richie - - + +Connecting Richie with one or more LMS | Richie + + -
    Version: 2.19.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    +
    Version: 2.19.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    Richie can be connected to an LMS in several ways, ranging from SSO to a fully integrated seamless experience.

    As of today, each approach has been implemented for OpenEdX but the same could be done for @@ -63,6 +63,6 @@

    Development

    If you want to activate seamless enrollment locally for development, you will need to set up TLS domains for both Richie and OpenEdX. To do this, head over to our -guide on setting-up TLS connections for Richie and OpenEdX.

    +guide on setting-up TLS connections for Richie and OpenEdX.

    \ No newline at end of file diff --git a/docs/2.19.0/native-installation/index.html b/docs/2.19.0/native-installation/index.html index b5939226ba..0b3aeef929 100644 --- a/docs/2.19.0/native-installation/index.html +++ b/docs/2.19.0/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.19.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.19.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native installation instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.19.0/synchronizing-course-runs/index.html b/docs/2.19.0/synchronizing-course-runs/index.html index ea87694a61..3484886639 100644 --- a/docs/2.19.0/synchronizing-course-runs/index.html +++ b/docs/2.19.0/synchronizing-course-runs/index.html @@ -2,10 +2,10 @@ - -Synchronizing course runs between Richie and OpenEdX | Richie - - + +Synchronizing course runs between Richie and OpenEdX | Richie + +
    Version: 2.19.0

    Synchronizing course runs between Richie and OpenEdX

    Richie can receive automatic course runs updates on a dedicated API endpoint.

    @@ -51,6 +51,6 @@

    import hashlib
    import hmac
    import json

    from django.conf import settings

    from microsite_configuration import microsite
    import requests
    from xmodule.modulestore.django import modulestore


    def update_course(course_key, *args, **kwargs):
    """Synchronize an OpenEdX course, identified by its course key, with a Richie instance."""
    course = modulestore().get_course(course_key)
    edxapp_domain = microsite.get_value("site_domain", settings.LMS_BASE)

    data = {
    "resource_link": "https://{:s}/courses/{!s}/info".format(
    edxapp_domain, course_key
    ),
    "start": course.start and course.start.isoformat(),
    "end": course.end and course.end.isoformat(),
    "enrollment_start": course.enrollment_start and course.enrollment_start.isoformat(),
    "enrollment_end": course.enrollment_end and course.enrollment_end.isoformat(),
    "languages": [course.language or settings.LANGUAGE_CODE],
    }

    signature = hmac.new(
    setting.COURSE_HOOK["secret"].encode("utf-8"),
    msg=json.dumps(data).encode("utf-8"),
    digestmod=hashlib.sha256,
    ).hexdigest()

    response = requests.post(
    setting.COURSE_HOOK["url"],
    json=data,
    headers={"Authorization": "SIG-HMAC-SHA256 {:s}".format(signature)},
    )

    Thanks to the signal emitted in OpenEdX, this function can then be triggered each time a course is modified and published:

    -
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    +
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    \ No newline at end of file diff --git a/docs/2.19.0/tls-connection/index.html b/docs/2.19.0/tls-connection/index.html index 507fd56090..a36e7238e8 100644 --- a/docs/2.19.0/tls-connection/index.html +++ b/docs/2.19.0/tls-connection/index.html @@ -2,10 +2,10 @@ - -Connecting Richie and OpenEdX over TLS for development | Richie - - + +Connecting Richie and OpenEdX over TLS for development | Richie + +
    Version: 2.19.0

    Connecting Richie and OpenEdX over TLS for development

    Purpose

    @@ -68,6 +68,6 @@

    $ make run-ssl

    Of course, you can still run apps without ssl by using:

    -
    $ make run
    +
    $ make run
    \ No newline at end of file diff --git a/docs/2.19.0/web-analytics/index.html b/docs/2.19.0/web-analytics/index.html index a620bd6aeb..277cae16cd 100644 --- a/docs/2.19.0/web-analytics/index.html +++ b/docs/2.19.0/web-analytics/index.html @@ -2,13 +2,13 @@ - -Add web analytics to your site | Richie - - + +Add web analytics to your site | Richie + + -
    Version: 2.19.0

    Add web analytics to your site

    Richie has native support to Google Analytics and Google Tag Manager Web Analytics solutions. +

    Version: 2.19.0

    Add web analytics to your site

    Richie has native support to Google Analytics and Google Tag Manager Web Analytics solutions. The purpose of this file is to explain how you can enable one of the supported Web Analytics providers and how you can extend Richie with an alternative solution.

    Google Analytics

    @@ -64,6 +64,6 @@

    +of src/frontend/js/utils/api/web-analytics/google_analytics.ts and change the src/frontend/js/utils/api/web-analytics/index.ts file to include that newer provider.

    \ No newline at end of file diff --git a/docs/2.2.0/accessibility-testing/index.html b/docs/2.2.0/accessibility-testing/index.html index a3e641be12..e981b82dfc 100644 --- a/docs/2.2.0/accessibility-testing/index.html +++ b/docs/2.2.0/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.2.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.2.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems in any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.2.0/building-the-frontend/index.html b/docs/2.2.0/building-the-frontend/index.html index 07449d85a8..7f2b6ec75c 100644 --- a/docs/2.2.0/building-the-frontend/index.html +++ b/docs/2.2.0/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.2.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.2.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.2.0/contributing-guide/index.html b/docs/2.2.0/contributing-guide/index.html index 4638518332..baf239547c 100644 --- a/docs/2.2.0/contributing-guide/index.html +++ b/docs/2.2.0/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.2.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.2.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.2.0/css-guidelines/index.html b/docs/2.2.0/css-guidelines/index.html index c059adad00..4dadf6f64e 100644 --- a/docs/2.2.0/css-guidelines/index.html +++ b/docs/2.2.0/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.2.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.2.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.2.0/discover/index.html b/docs/2.2.0/discover/index.html index d36d3f7418..5930edacfa 100644 --- a/docs/2.2.0/discover/index.html +++ b/docs/2.2.0/discover/index.html @@ -2,13 +2,13 @@ - -Getting started with Richie | Richie - - + +Getting started with Richie | Richie + + -
    Version: 2.2.0

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    +
    Version: 2.2.0

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    Login/password are admin/admin. The database is regularly flushed.

    Architecture

    Richie is a container-native application but can also be installed @@ -60,6 +60,6 @@

    Advanced - Connecting Richie to OpenEdx

    If you want users to enroll on courses in OpenEdx directly from Richie via API calls, you should read the advanced guide to connect -Richie to OpenEdx over TLS.

    +Richie to OpenEdx over TLS.

    \ No newline at end of file diff --git a/docs/2.2.0/django-react-interop/index.html b/docs/2.2.0/django-react-interop/index.html index 56d080f871..97875406d9 100644 --- a/docs/2.2.0/django-react-interop/index.html +++ b/docs/2.2.0/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.2.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.2.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -64,6 +64,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.2.0/docker-development/index.html b/docs/2.2.0/docker-development/index.html index a1e868929d..bcf0b14d07 100644 --- a/docs/2.2.0/docker-development/index.html +++ b/docs/2.2.0/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.2.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.2.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.2.0/frontend-overrides/index.html b/docs/2.2.0/frontend-overrides/index.html index fe65fb1c01..5e30be996a 100644 --- a/docs/2.2.0/frontend-overrides/index.html +++ b/docs/2.2.0/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.2.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.2.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.2.0/internationalization/index.html b/docs/2.2.0/internationalization/index.html index e11da038e3..9ce4e8d0b9 100644 --- a/docs/2.2.0/internationalization/index.html +++ b/docs/2.2.0/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.2.0

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.2.0

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.2.0/lms-connection/index.html b/docs/2.2.0/lms-connection/index.html index b70834b8f9..7efd785082 100644 --- a/docs/2.2.0/lms-connection/index.html +++ b/docs/2.2.0/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with an LMS | Richie - - + +Connecting Richie with an LMS | Richie + + -
    Version: 2.2.0

    Connecting Richie with an LMS

    richie can be connected to one or more Learning Management Systems (LMS) like OpenEdx, Moodle +

    Version: 2.2.0

    Connecting Richie with an LMS

    richie can be connected to one or more Learning Management Systems (LMS) like OpenEdx, Moodle or Canvas for a seamless experience between browsing the course catalog on richie and following the course itself on the LMS.

    In order to connect richie with a LMS, there is an API bridge @@ -81,6 +81,6 @@

    https://richie.local.dev:8070 without browser warning about the certificate validity.

    You need to follow these steps once. If you want to use SSL later, just use make run-ssl to run OpenEdx and Richie apps. -Of course, you can still run apps without ssl by using make run.

    +Of course, you can still run apps without ssl by using make run.

    \ No newline at end of file diff --git a/docs/2.2.0/native-installation/index.html b/docs/2.2.0/native-installation/index.html index ab453eb637..a527ca1154 100644 --- a/docs/2.2.0/native-installation/index.html +++ b/docs/2.2.0/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.2.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.2.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.20.0/accessibility-testing/index.html b/docs/2.20.0/accessibility-testing/index.html index 6172124af6..e4e85b86ac 100644 --- a/docs/2.20.0/accessibility-testing/index.html +++ b/docs/2.20.0/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.20.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.20.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems on any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.20.0/api/course-run-synchronization-api/index.html b/docs/2.20.0/api/course-run-synchronization-api/index.html index 7ab1b945d8..b0fd29205c 100644 --- a/docs/2.20.0/api/course-run-synchronization-api/index.html +++ b/docs/2.20.0/api/course-run-synchronization-api/index.html @@ -2,10 +2,10 @@ - -Course run synchronization API | Richie - - + +Course run synchronization API | Richie + +
    Version: 2.20.0

    Course run synchronization API

    API endpoint allowing remote systems to synchronize their course runs with a Richie instance.

    @@ -52,6 +52,6 @@

    +
    \ No newline at end of file diff --git a/docs/2.20.0/building-the-frontend/index.html b/docs/2.20.0/building-the-frontend/index.html index d6db088c41..4971127dde 100644 --- a/docs/2.20.0/building-the-frontend/index.html +++ b/docs/2.20.0/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.20.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.20.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.20.0/contributing-guide/index.html b/docs/2.20.0/contributing-guide/index.html index 1de4718462..f159d966f8 100644 --- a/docs/2.20.0/contributing-guide/index.html +++ b/docs/2.20.0/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.20.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.20.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.20.0/cookiecutter/index.html b/docs/2.20.0/cookiecutter/index.html index 2b17bdcfec..f4e157756d 100644 --- a/docs/2.20.0/cookiecutter/index.html +++ b/docs/2.20.0/cookiecutter/index.html @@ -2,13 +2,13 @@ - -Start your own site | Richie - - + +Start your own site | Richie + + -
    Version: 2.20.0

    Start your own site

    We use Cookiecutter to help you +

    Version: 2.20.0

    Start your own site

    We use Cookiecutter to help you set up a production-ready learning portal website based on Richie in seconds.

    Run Cookiecutter

    @@ -73,6 +73,6 @@

    cookiecutter --overwrite-if-exists gh:openfun/richie --directory=cookiecutter

    Help us improve this project

    After starting your project, please submit an issue let us know how it went and -what other features we should add to make it better.

    +what other features we should add to make it better.

    \ No newline at end of file diff --git a/docs/2.20.0/css-guidelines/index.html b/docs/2.20.0/css-guidelines/index.html index abbfb5ded0..45168b37af 100644 --- a/docs/2.20.0/css-guidelines/index.html +++ b/docs/2.20.0/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.20.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.20.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.20.0/discover/index.html b/docs/2.20.0/discover/index.html index 2d143d3585..dc364cf00e 100644 --- a/docs/2.20.0/discover/index.html +++ b/docs/2.20.0/discover/index.html @@ -2,13 +2,13 @@ - -Discover Richie | Richie - - + +Discover Richie | Richie + + -
    Version: 2.20.0

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online +

    Version: 2.20.0

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online courses and MOOCs.

    However, if you need to build a complete website with flexible content to aggregate your courses, in several languages and from different sources, you will soon need a CMS.

    @@ -51,6 +51,6 @@

    Start yo
  • override some css rules or rebuild the whole css with your own variables and customizations,
  • add any DjangoCMS plugin or feature,
  • add any Django third-party application.
  • -

    +
    \ No newline at end of file diff --git a/docs/2.20.0/displaying-connection-status/index.html b/docs/2.20.0/displaying-connection-status/index.html index 3ded93a78a..d6c49e0388 100644 --- a/docs/2.20.0/displaying-connection-status/index.html +++ b/docs/2.20.0/displaying-connection-status/index.html @@ -2,10 +2,10 @@ - -Displaying OpenEdX connection status in Richie | Richie - - + +Displaying OpenEdX connection status in Richie | Richie + + +
    \ No newline at end of file diff --git a/docs/2.20.0/django-react-interop/index.html b/docs/2.20.0/django-react-interop/index.html index 9f34aadf94..079ae84b87 100644 --- a/docs/2.20.0/django-react-interop/index.html +++ b/docs/2.20.0/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.20.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.20.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -64,6 +64,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.20.0/docker-development/index.html b/docs/2.20.0/docker-development/index.html index 91f7f8c242..846df6e784 100644 --- a/docs/2.20.0/docker-development/index.html +++ b/docs/2.20.0/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.20.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.20.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.20.0/filters-customization/index.html b/docs/2.20.0/filters-customization/index.html index 06d74747a4..0b7cf2f4d2 100644 --- a/docs/2.20.0/filters-customization/index.html +++ b/docs/2.20.0/filters-customization/index.html @@ -2,13 +2,13 @@ - -Customizing search filters | Richie - - + +Customizing search filters | Richie + + -
    Version: 2.20.0

    Customizing search filters

    You may want to customize the filters on the left side bar of the search page.

    +
    Version: 2.20.0

    Customizing search filters

    You may want to customize the filters on the left side bar of the search page.

    Richie makes it easy to choose which filters you want to display among the existing filters and in which order. You can also configure the existing filters to change their title or the way they behave. Lastly, you can completely override a filter or create your own custom filter @@ -88,6 +88,6 @@

    opening an issue!

    +opening an issue!

    \ No newline at end of file diff --git a/docs/2.20.0/frontend-overrides/index.html b/docs/2.20.0/frontend-overrides/index.html index d9684cd726..d75a86a478 100644 --- a/docs/2.20.0/frontend-overrides/index.html +++ b/docs/2.20.0/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.20.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.20.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.20.0/installation/index.html b/docs/2.20.0/installation/index.html index 62850533b7..e413a5bbea 100644 --- a/docs/2.20.0/installation/index.html +++ b/docs/2.20.0/installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie for development | Richie - - + +Installing Richie for development | Richie + + -
    Version: 2.20.0

    Installing Richie for development

    Richie is a container-native application but can also be installed +

    +https://www.nau.edu.pt.

    \ No newline at end of file diff --git a/docs/2.20.0/internationalization/index.html b/docs/2.20.0/internationalization/index.html index 1424f52287..a1e1fc0952 100644 --- a/docs/2.20.0/internationalization/index.html +++ b/docs/2.20.0/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.20.0

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.20.0

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.20.0/joanie-connection/index.html b/docs/2.20.0/joanie-connection/index.html index e09ec76e59..3550592c11 100644 --- a/docs/2.20.0/joanie-connection/index.html +++ b/docs/2.20.0/joanie-connection/index.html @@ -2,10 +2,10 @@ - -Joanie Connection | Richie - - + +Joanie Connection | Richie + +
    Version: 2.20.0

    Joanie Connection

    Joanie delivers an API able to manage course @@ -90,6 +90,6 @@

    Lifet its lifetime is 5 minutes by default.

    Technical support

    If you encounter an issue with this documentation, please -open an issue on our repository.

    +open an issue on our repository.

    \ No newline at end of file diff --git a/docs/2.20.0/lms-backends/index.html b/docs/2.20.0/lms-backends/index.html index 4cd4b6fd0e..8bb8552c2b 100644 --- a/docs/2.20.0/lms-backends/index.html +++ b/docs/2.20.0/lms-backends/index.html @@ -2,10 +2,10 @@ - -Configuring LMS Backends | Richie - - + +Configuring LMS Backends | Richie + +
    Version: 2.20.0

    Configuring LMS Backends

    Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless @@ -115,6 +115,6 @@

    Technical

    If you encounter an issue with this documentation or the backends included in Richie, please open an issue on our repository.

    If you need a custom backend, you can submit a PR or -open an issue and we will consider adding it.

    +open an issue and we will consider adding it.

    \ No newline at end of file diff --git a/docs/2.20.0/lms-connection/index.html b/docs/2.20.0/lms-connection/index.html index b5314a142e..def3a798b4 100644 --- a/docs/2.20.0/lms-connection/index.html +++ b/docs/2.20.0/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with one or more LMS | Richie - - + +Connecting Richie with one or more LMS | Richie + + -
    Version: 2.20.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    +
    Version: 2.20.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    Richie can be connected to an LMS in several ways, ranging from SSO to a fully integrated seamless experience.

    As of today, each approach has been implemented for OpenEdX but the same could be done for @@ -63,6 +63,6 @@

    Development

    If you want to activate seamless enrollment locally for development, you will need to set up TLS domains for both Richie and OpenEdX. To do this, head over to our -guide on setting-up TLS connections for Richie and OpenEdX.

    +guide on setting-up TLS connections for Richie and OpenEdX.

    \ No newline at end of file diff --git a/docs/2.20.0/native-installation/index.html b/docs/2.20.0/native-installation/index.html index 1d4f8de33a..93062b8698 100644 --- a/docs/2.20.0/native-installation/index.html +++ b/docs/2.20.0/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.20.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.20.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native installation instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.20.0/synchronizing-course-runs/index.html b/docs/2.20.0/synchronizing-course-runs/index.html index 026543bedf..d2aeeb6213 100644 --- a/docs/2.20.0/synchronizing-course-runs/index.html +++ b/docs/2.20.0/synchronizing-course-runs/index.html @@ -2,10 +2,10 @@ - -Synchronizing course runs between Richie and OpenEdX | Richie - - + +Synchronizing course runs between Richie and OpenEdX | Richie + +
    Version: 2.20.0

    Synchronizing course runs between Richie and OpenEdX

    Richie can receive automatic course runs updates on a dedicated API endpoint.

    @@ -51,6 +51,6 @@

    import hashlib
    import hmac
    import json

    from django.conf import settings

    from microsite_configuration import microsite
    import requests
    from xmodule.modulestore.django import modulestore


    def update_course(course_key, *args, **kwargs):
    """Synchronize an OpenEdX course, identified by its course key, with a Richie instance."""
    course = modulestore().get_course(course_key)
    edxapp_domain = microsite.get_value("site_domain", settings.LMS_BASE)

    data = {
    "resource_link": "https://{:s}/courses/{!s}/info".format(
    edxapp_domain, course_key
    ),
    "start": course.start and course.start.isoformat(),
    "end": course.end and course.end.isoformat(),
    "enrollment_start": course.enrollment_start and course.enrollment_start.isoformat(),
    "enrollment_end": course.enrollment_end and course.enrollment_end.isoformat(),
    "languages": [course.language or settings.LANGUAGE_CODE],
    }

    signature = hmac.new(
    setting.COURSE_HOOK["secret"].encode("utf-8"),
    msg=json.dumps(data).encode("utf-8"),
    digestmod=hashlib.sha256,
    ).hexdigest()

    response = requests.post(
    setting.COURSE_HOOK["url"],
    json=data,
    headers={"Authorization": "SIG-HMAC-SHA256 {:s}".format(signature)},
    )

    Thanks to the signal emitted in OpenEdX, this function can then be triggered each time a course is modified and published:

    -
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    +
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    \ No newline at end of file diff --git a/docs/2.20.0/tls-connection/index.html b/docs/2.20.0/tls-connection/index.html index ea0697506f..0262bb1fd4 100644 --- a/docs/2.20.0/tls-connection/index.html +++ b/docs/2.20.0/tls-connection/index.html @@ -2,10 +2,10 @@ - -Connecting Richie and OpenEdX over TLS for development | Richie - - + +Connecting Richie and OpenEdX over TLS for development | Richie + +
    Version: 2.20.0

    Connecting Richie and OpenEdX over TLS for development

    Purpose

    @@ -68,6 +68,6 @@

    $ make run-ssl

    Of course, you can still run apps without ssl by using:

    -
    $ make run
    +
    $ make run
    \ No newline at end of file diff --git a/docs/2.20.0/web-analytics/index.html b/docs/2.20.0/web-analytics/index.html index 6753379ae1..2ec12c1330 100644 --- a/docs/2.20.0/web-analytics/index.html +++ b/docs/2.20.0/web-analytics/index.html @@ -2,13 +2,13 @@ - -Add web analytics to your site | Richie - - + +Add web analytics to your site | Richie + + -
    Version: 2.20.0

    Add web analytics to your site

    Richie has native support to Google Analytics and Google Tag Manager Web Analytics solutions. +

    Version: 2.20.0

    Add web analytics to your site

    Richie has native support to Google Analytics and Google Tag Manager Web Analytics solutions. The purpose of this file is to explain how you can enable one of the supported Web Analytics providers and how you can extend Richie with an alternative solution.

    Google Analytics

    @@ -64,6 +64,6 @@

    +of src/frontend/js/utils/api/web-analytics/google_analytics.ts and change the src/frontend/js/utils/api/web-analytics/index.ts file to include that newer provider.

    \ No newline at end of file diff --git a/docs/2.20.1/accessibility-testing/index.html b/docs/2.20.1/accessibility-testing/index.html index 041252ef03..0b1e3a0105 100644 --- a/docs/2.20.1/accessibility-testing/index.html +++ b/docs/2.20.1/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.20.1

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.20.1

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems on any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.20.1/api/course-run-synchronization-api/index.html b/docs/2.20.1/api/course-run-synchronization-api/index.html index 86a2733f04..d8e07e6f82 100644 --- a/docs/2.20.1/api/course-run-synchronization-api/index.html +++ b/docs/2.20.1/api/course-run-synchronization-api/index.html @@ -2,10 +2,10 @@ - -Course run synchronization API | Richie - - + +Course run synchronization API | Richie + +
    Version: 2.20.1

    Course run synchronization API

    API endpoint allowing remote systems to synchronize their course runs with a Richie instance.

    @@ -52,6 +52,6 @@

    +
    \ No newline at end of file diff --git a/docs/2.20.1/building-the-frontend/index.html b/docs/2.20.1/building-the-frontend/index.html index 48fc9399f0..5d898cd9f9 100644 --- a/docs/2.20.1/building-the-frontend/index.html +++ b/docs/2.20.1/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.20.1

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.20.1

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.20.1/contributing-guide/index.html b/docs/2.20.1/contributing-guide/index.html index 80c622d927..8e8125de3f 100644 --- a/docs/2.20.1/contributing-guide/index.html +++ b/docs/2.20.1/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.20.1

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.20.1

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.20.1/cookiecutter/index.html b/docs/2.20.1/cookiecutter/index.html index f1edadd358..647b129f19 100644 --- a/docs/2.20.1/cookiecutter/index.html +++ b/docs/2.20.1/cookiecutter/index.html @@ -2,13 +2,13 @@ - -Start your own site | Richie - - + +Start your own site | Richie + + -
    Version: 2.20.1

    Start your own site

    We use Cookiecutter to help you +

    Version: 2.20.1

    Start your own site

    We use Cookiecutter to help you set up a production-ready learning portal website based on Richie in seconds.

    Run Cookiecutter

    @@ -73,6 +73,6 @@

    cookiecutter --overwrite-if-exists gh:openfun/richie --directory=cookiecutter

    Help us improve this project

    After starting your project, please submit an issue let us know how it went and -what other features we should add to make it better.

    +what other features we should add to make it better.

    \ No newline at end of file diff --git a/docs/2.20.1/css-guidelines/index.html b/docs/2.20.1/css-guidelines/index.html index 12f2e027eb..12a58b39d3 100644 --- a/docs/2.20.1/css-guidelines/index.html +++ b/docs/2.20.1/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.20.1

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.20.1

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.20.1/discover/index.html b/docs/2.20.1/discover/index.html index 45d710d9b8..8b295c01a5 100644 --- a/docs/2.20.1/discover/index.html +++ b/docs/2.20.1/discover/index.html @@ -2,13 +2,13 @@ - -Discover Richie | Richie - - + +Discover Richie | Richie + + -
    Version: 2.20.1

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online +

    Version: 2.20.1

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online courses and MOOCs.

    However, if you need to build a complete website with flexible content to aggregate your courses, in several languages and from different sources, you will soon need a CMS.

    @@ -51,6 +51,6 @@

    Start yo
  • override some css rules or rebuild the whole css with your own variables and customizations,
  • add any DjangoCMS plugin or feature,
  • add any Django third-party application.
  • -

    +
    \ No newline at end of file diff --git a/docs/2.20.1/displaying-connection-status/index.html b/docs/2.20.1/displaying-connection-status/index.html index 207828c12f..374014e9d8 100644 --- a/docs/2.20.1/displaying-connection-status/index.html +++ b/docs/2.20.1/displaying-connection-status/index.html @@ -2,10 +2,10 @@ - -Displaying OpenEdX connection status in Richie | Richie - - + +Displaying OpenEdX connection status in Richie | Richie + + +
    \ No newline at end of file diff --git a/docs/2.20.1/django-react-interop/index.html b/docs/2.20.1/django-react-interop/index.html index aa10036aec..919c70c069 100644 --- a/docs/2.20.1/django-react-interop/index.html +++ b/docs/2.20.1/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.20.1

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.20.1

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -64,6 +64,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.20.1/docker-development/index.html b/docs/2.20.1/docker-development/index.html index fad934a21b..06a82a7ca2 100644 --- a/docs/2.20.1/docker-development/index.html +++ b/docs/2.20.1/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.20.1

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.20.1

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.20.1/filters-customization/index.html b/docs/2.20.1/filters-customization/index.html index 48de2309c4..c4380e93ee 100644 --- a/docs/2.20.1/filters-customization/index.html +++ b/docs/2.20.1/filters-customization/index.html @@ -2,13 +2,13 @@ - -Customizing search filters | Richie - - + +Customizing search filters | Richie + + -
    Version: 2.20.1

    Customizing search filters

    You may want to customize the filters on the left side bar of the search page.

    +
    Version: 2.20.1

    Customizing search filters

    You may want to customize the filters on the left side bar of the search page.

    Richie makes it easy to choose which filters you want to display among the existing filters and in which order. You can also configure the existing filters to change their title or the way they behave. Lastly, you can completely override a filter or create your own custom filter @@ -88,6 +88,6 @@

    opening an issue!

    +opening an issue!

    \ No newline at end of file diff --git a/docs/2.20.1/frontend-overrides/index.html b/docs/2.20.1/frontend-overrides/index.html index aa4308f4ce..7e095c5f6e 100644 --- a/docs/2.20.1/frontend-overrides/index.html +++ b/docs/2.20.1/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.20.1

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.20.1

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.20.1/installation/index.html b/docs/2.20.1/installation/index.html index 5cc440607a..83ab5aaeae 100644 --- a/docs/2.20.1/installation/index.html +++ b/docs/2.20.1/installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie for development | Richie - - + +Installing Richie for development | Richie + + -
    Version: 2.20.1

    Installing Richie for development

    Richie is a container-native application but can also be installed +

    +https://www.nau.edu.pt.

    \ No newline at end of file diff --git a/docs/2.20.1/internationalization/index.html b/docs/2.20.1/internationalization/index.html index 9593ba3cdf..59ff101a7f 100644 --- a/docs/2.20.1/internationalization/index.html +++ b/docs/2.20.1/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.20.1

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.20.1

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.20.1/joanie-connection/index.html b/docs/2.20.1/joanie-connection/index.html index 3aef7de0af..291a63cbf0 100644 --- a/docs/2.20.1/joanie-connection/index.html +++ b/docs/2.20.1/joanie-connection/index.html @@ -2,10 +2,10 @@ - -Joanie Connection | Richie - - + +Joanie Connection | Richie + +
    Version: 2.20.1

    Joanie Connection

    Joanie delivers an API able to manage course @@ -90,6 +90,6 @@

    Lifet its lifetime is 5 minutes by default.

    Technical support

    If you encounter an issue with this documentation, please -open an issue on our repository.

    +open an issue on our repository.

    \ No newline at end of file diff --git a/docs/2.20.1/lms-backends/index.html b/docs/2.20.1/lms-backends/index.html index 2af7bf7e0a..f952a805cc 100644 --- a/docs/2.20.1/lms-backends/index.html +++ b/docs/2.20.1/lms-backends/index.html @@ -2,10 +2,10 @@ - -Configuring LMS Backends | Richie - - + +Configuring LMS Backends | Richie + +
    Version: 2.20.1

    Configuring LMS Backends

    Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless @@ -115,6 +115,6 @@

    Technical

    If you encounter an issue with this documentation or the backends included in Richie, please open an issue on our repository.

    If you need a custom backend, you can submit a PR or -open an issue and we will consider adding it.

    +open an issue and we will consider adding it.

    \ No newline at end of file diff --git a/docs/2.20.1/lms-connection/index.html b/docs/2.20.1/lms-connection/index.html index 46f1c7ef92..ee3295defe 100644 --- a/docs/2.20.1/lms-connection/index.html +++ b/docs/2.20.1/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with one or more LMS | Richie - - + +Connecting Richie with one or more LMS | Richie + + -
    Version: 2.20.1

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    +
    Version: 2.20.1

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    Richie can be connected to an LMS in several ways, ranging from SSO to a fully integrated seamless experience.

    As of today, each approach has been implemented for OpenEdX but the same could be done for @@ -63,6 +63,6 @@

    Development

    If you want to activate seamless enrollment locally for development, you will need to set up TLS domains for both Richie and OpenEdX. To do this, head over to our -guide on setting-up TLS connections for Richie and OpenEdX.

    +guide on setting-up TLS connections for Richie and OpenEdX.

    \ No newline at end of file diff --git a/docs/2.20.1/native-installation/index.html b/docs/2.20.1/native-installation/index.html index 76f3183241..2c10d9965e 100644 --- a/docs/2.20.1/native-installation/index.html +++ b/docs/2.20.1/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.20.1

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.20.1

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native installation instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.20.1/synchronizing-course-runs/index.html b/docs/2.20.1/synchronizing-course-runs/index.html index 05df5dc5a8..5946f350b8 100644 --- a/docs/2.20.1/synchronizing-course-runs/index.html +++ b/docs/2.20.1/synchronizing-course-runs/index.html @@ -2,10 +2,10 @@ - -Synchronizing course runs between Richie and OpenEdX | Richie - - + +Synchronizing course runs between Richie and OpenEdX | Richie + +
    Version: 2.20.1

    Synchronizing course runs between Richie and OpenEdX

    Richie can receive automatic course runs updates on a dedicated API endpoint.

    @@ -51,6 +51,6 @@

    import hashlib
    import hmac
    import json

    from django.conf import settings

    from microsite_configuration import microsite
    import requests
    from xmodule.modulestore.django import modulestore


    def update_course(course_key, *args, **kwargs):
    """Synchronize an OpenEdX course, identified by its course key, with a Richie instance."""
    course = modulestore().get_course(course_key)
    edxapp_domain = microsite.get_value("site_domain", settings.LMS_BASE)

    data = {
    "resource_link": "https://{:s}/courses/{!s}/info".format(
    edxapp_domain, course_key
    ),
    "start": course.start and course.start.isoformat(),
    "end": course.end and course.end.isoformat(),
    "enrollment_start": course.enrollment_start and course.enrollment_start.isoformat(),
    "enrollment_end": course.enrollment_end and course.enrollment_end.isoformat(),
    "languages": [course.language or settings.LANGUAGE_CODE],
    }

    signature = hmac.new(
    setting.COURSE_HOOK["secret"].encode("utf-8"),
    msg=json.dumps(data).encode("utf-8"),
    digestmod=hashlib.sha256,
    ).hexdigest()

    response = requests.post(
    setting.COURSE_HOOK["url"],
    json=data,
    headers={"Authorization": "SIG-HMAC-SHA256 {:s}".format(signature)},
    )

    Thanks to the signal emitted in OpenEdX, this function can then be triggered each time a course is modified and published:

    -
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    +
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    \ No newline at end of file diff --git a/docs/2.20.1/tls-connection/index.html b/docs/2.20.1/tls-connection/index.html index 379c5832dd..9f72663616 100644 --- a/docs/2.20.1/tls-connection/index.html +++ b/docs/2.20.1/tls-connection/index.html @@ -2,10 +2,10 @@ - -Connecting Richie and OpenEdX over TLS for development | Richie - - + +Connecting Richie and OpenEdX over TLS for development | Richie + +
    Version: 2.20.1

    Connecting Richie and OpenEdX over TLS for development

    Purpose

    @@ -68,6 +68,6 @@

    $ make run-ssl

    Of course, you can still run apps without ssl by using:

    -
    $ make run
    +
    $ make run
    \ No newline at end of file diff --git a/docs/2.20.1/web-analytics/index.html b/docs/2.20.1/web-analytics/index.html index afe4193b3e..12505b81d2 100644 --- a/docs/2.20.1/web-analytics/index.html +++ b/docs/2.20.1/web-analytics/index.html @@ -2,13 +2,13 @@ - -Add web analytics to your site | Richie - - + +Add web analytics to your site | Richie + + -
    Version: 2.20.1

    Add web analytics to your site

    Richie has native support to Google Analytics and Google Tag Manager Web Analytics solutions. +

    Version: 2.20.1

    Add web analytics to your site

    Richie has native support to Google Analytics and Google Tag Manager Web Analytics solutions. The purpose of this file is to explain how you can enable one of the supported Web Analytics providers and how you can extend Richie with an alternative solution.

    Google Analytics

    @@ -64,6 +64,6 @@

    +of src/frontend/js/utils/api/web-analytics/google_analytics.ts and change the src/frontend/js/utils/api/web-analytics/index.ts file to include that newer provider.

    \ No newline at end of file diff --git a/docs/2.21.0/accessibility-testing/index.html b/docs/2.21.0/accessibility-testing/index.html index 2118e1e66b..2cdf0f8345 100644 --- a/docs/2.21.0/accessibility-testing/index.html +++ b/docs/2.21.0/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.21.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.21.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems on any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.21.0/api/course-run-synchronization-api/index.html b/docs/2.21.0/api/course-run-synchronization-api/index.html index 02a3d68b5c..7db60001d8 100644 --- a/docs/2.21.0/api/course-run-synchronization-api/index.html +++ b/docs/2.21.0/api/course-run-synchronization-api/index.html @@ -2,10 +2,10 @@ - -Course run synchronization API | Richie - - + +Course run synchronization API | Richie + +
    Version: 2.21.0

    Course run synchronization API

    API endpoint allowing remote systems to synchronize their course runs with a Richie instance.

    @@ -52,6 +52,6 @@

    +
    \ No newline at end of file diff --git a/docs/2.21.0/building-the-frontend/index.html b/docs/2.21.0/building-the-frontend/index.html index d03b5121db..47b600f370 100644 --- a/docs/2.21.0/building-the-frontend/index.html +++ b/docs/2.21.0/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.21.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.21.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.21.0/contributing-guide/index.html b/docs/2.21.0/contributing-guide/index.html index 06e14695ae..8fd1a8137b 100644 --- a/docs/2.21.0/contributing-guide/index.html +++ b/docs/2.21.0/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.21.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.21.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.21.0/cookiecutter/index.html b/docs/2.21.0/cookiecutter/index.html index 7668e78b3f..f078ad207d 100644 --- a/docs/2.21.0/cookiecutter/index.html +++ b/docs/2.21.0/cookiecutter/index.html @@ -2,13 +2,13 @@ - -Start your own site | Richie - - + +Start your own site | Richie + + -
    Version: 2.21.0

    Start your own site

    We use Cookiecutter to help you +

    Version: 2.21.0

    Start your own site

    We use Cookiecutter to help you set up a production-ready learning portal website based on Richie in seconds.

    Run Cookiecutter

    @@ -73,6 +73,6 @@

    cookiecutter --overwrite-if-exists gh:openfun/richie --directory=cookiecutter

    Help us improve this project

    After starting your project, please submit an issue let us know how it went and -what other features we should add to make it better.

    +what other features we should add to make it better.

    \ No newline at end of file diff --git a/docs/2.21.0/css-guidelines/index.html b/docs/2.21.0/css-guidelines/index.html index eba672ff8a..13f914e6a2 100644 --- a/docs/2.21.0/css-guidelines/index.html +++ b/docs/2.21.0/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.21.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.21.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.21.0/discover/index.html b/docs/2.21.0/discover/index.html index cdd62af3b1..8eaf7fcf76 100644 --- a/docs/2.21.0/discover/index.html +++ b/docs/2.21.0/discover/index.html @@ -2,13 +2,13 @@ - -Discover Richie | Richie - - + +Discover Richie | Richie + + -
    Version: 2.21.0

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online +

    Version: 2.21.0

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online courses and MOOCs.

    However, if you need to build a complete website with flexible content to aggregate your courses, in several languages and from different sources, you will soon need a CMS.

    @@ -51,6 +51,6 @@

    Start yo
  • override some css rules or rebuild the whole css with your own variables and customizations,
  • add any DjangoCMS plugin or feature,
  • add any Django third-party application.
  • -

    +
    \ No newline at end of file diff --git a/docs/2.21.0/displaying-connection-status/index.html b/docs/2.21.0/displaying-connection-status/index.html index cd137023d3..351c8662a6 100644 --- a/docs/2.21.0/displaying-connection-status/index.html +++ b/docs/2.21.0/displaying-connection-status/index.html @@ -2,10 +2,10 @@ - -Displaying OpenEdX connection status in Richie | Richie - - + +Displaying OpenEdX connection status in Richie | Richie + + +
    \ No newline at end of file diff --git a/docs/2.21.0/django-react-interop/index.html b/docs/2.21.0/django-react-interop/index.html index 83f5b93768..73fcceb22d 100644 --- a/docs/2.21.0/django-react-interop/index.html +++ b/docs/2.21.0/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.21.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.21.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -64,6 +64,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.21.0/docker-development/index.html b/docs/2.21.0/docker-development/index.html index 916f57fa78..29c05ac97d 100644 --- a/docs/2.21.0/docker-development/index.html +++ b/docs/2.21.0/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.21.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.21.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.21.0/filters-customization/index.html b/docs/2.21.0/filters-customization/index.html index 708126c842..e881dc8833 100644 --- a/docs/2.21.0/filters-customization/index.html +++ b/docs/2.21.0/filters-customization/index.html @@ -2,13 +2,13 @@ - -Customizing search filters | Richie - - + +Customizing search filters | Richie + + -
    Version: 2.21.0

    Customizing search filters

    You may want to customize the filters on the left side bar of the search page.

    +
    Version: 2.21.0

    Customizing search filters

    You may want to customize the filters on the left side bar of the search page.

    Richie makes it easy to choose which filters you want to display among the existing filters and in which order. You can also configure the existing filters to change their title or the way they behave. Lastly, you can completely override a filter or create your own custom filter @@ -88,6 +88,6 @@

    opening an issue!

    +opening an issue!

    \ No newline at end of file diff --git a/docs/2.21.0/frontend-overrides/index.html b/docs/2.21.0/frontend-overrides/index.html index 8c5f288dad..df4757109a 100644 --- a/docs/2.21.0/frontend-overrides/index.html +++ b/docs/2.21.0/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.21.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.21.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.21.0/installation/index.html b/docs/2.21.0/installation/index.html index 809b034d2b..31bd326c53 100644 --- a/docs/2.21.0/installation/index.html +++ b/docs/2.21.0/installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie for development | Richie - - + +Installing Richie for development | Richie + + -
    Version: 2.21.0

    Installing Richie for development

    Richie is a container-native application but can also be installed +

    +https://www.nau.edu.pt.

    \ No newline at end of file diff --git a/docs/2.21.0/internationalization/index.html b/docs/2.21.0/internationalization/index.html index 3479966127..f19b334750 100644 --- a/docs/2.21.0/internationalization/index.html +++ b/docs/2.21.0/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.21.0

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.21.0

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.21.0/joanie-connection/index.html b/docs/2.21.0/joanie-connection/index.html index 84f6d2c308..bddfa2247b 100644 --- a/docs/2.21.0/joanie-connection/index.html +++ b/docs/2.21.0/joanie-connection/index.html @@ -2,10 +2,10 @@ - -Joanie Connection | Richie - - + +Joanie Connection | Richie + +
    Version: 2.21.0

    Joanie Connection

    Joanie delivers an API able to manage course @@ -90,6 +90,6 @@

    Lifet its lifetime is 5 minutes by default.

    Technical support

    If you encounter an issue with this documentation, please -open an issue on our repository.

    +open an issue on our repository.

    \ No newline at end of file diff --git a/docs/2.21.0/lms-backends/index.html b/docs/2.21.0/lms-backends/index.html index 1fce5463fc..d7d850ad1e 100644 --- a/docs/2.21.0/lms-backends/index.html +++ b/docs/2.21.0/lms-backends/index.html @@ -2,10 +2,10 @@ - -Configuring LMS Backends | Richie - - + +Configuring LMS Backends | Richie + +
    Version: 2.21.0

    Configuring LMS Backends

    Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless @@ -115,6 +115,6 @@

    Technical

    If you encounter an issue with this documentation or the backends included in Richie, please open an issue on our repository.

    If you need a custom backend, you can submit a PR or -open an issue and we will consider adding it.

    +open an issue and we will consider adding it.

    \ No newline at end of file diff --git a/docs/2.21.0/lms-connection/index.html b/docs/2.21.0/lms-connection/index.html index 3a069edf50..cd004c385d 100644 --- a/docs/2.21.0/lms-connection/index.html +++ b/docs/2.21.0/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with one or more LMS | Richie - - + +Connecting Richie with one or more LMS | Richie + + -
    Version: 2.21.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    +
    Version: 2.21.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    Richie can be connected to an LMS in several ways, ranging from SSO to a fully integrated seamless experience.

    As of today, each approach has been implemented for OpenEdX but the same could be done for @@ -63,6 +63,6 @@

    Development

    If you want to activate seamless enrollment locally for development, you will need to set up TLS domains for both Richie and OpenEdX. To do this, head over to our -guide on setting-up TLS connections for Richie and OpenEdX.

    +guide on setting-up TLS connections for Richie and OpenEdX.

    \ No newline at end of file diff --git a/docs/2.21.0/native-installation/index.html b/docs/2.21.0/native-installation/index.html index d755e1ea93..960a2480e6 100644 --- a/docs/2.21.0/native-installation/index.html +++ b/docs/2.21.0/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.21.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.21.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native installation instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.21.0/synchronizing-course-runs/index.html b/docs/2.21.0/synchronizing-course-runs/index.html index f5cdc2e005..1c5553e9e9 100644 --- a/docs/2.21.0/synchronizing-course-runs/index.html +++ b/docs/2.21.0/synchronizing-course-runs/index.html @@ -2,10 +2,10 @@ - -Synchronizing course runs between Richie and OpenEdX | Richie - - + +Synchronizing course runs between Richie and OpenEdX | Richie + +
    Version: 2.21.0

    Synchronizing course runs between Richie and OpenEdX

    Richie can receive automatic course runs updates on a dedicated API endpoint.

    @@ -51,6 +51,6 @@

    import hashlib
    import hmac
    import json

    from django.conf import settings

    from microsite_configuration import microsite
    import requests
    from xmodule.modulestore.django import modulestore


    def update_course(course_key, *args, **kwargs):
    """Synchronize an OpenEdX course, identified by its course key, with a Richie instance."""
    course = modulestore().get_course(course_key)
    edxapp_domain = microsite.get_value("site_domain", settings.LMS_BASE)

    data = {
    "resource_link": "https://{:s}/courses/{!s}/info".format(
    edxapp_domain, course_key
    ),
    "start": course.start and course.start.isoformat(),
    "end": course.end and course.end.isoformat(),
    "enrollment_start": course.enrollment_start and course.enrollment_start.isoformat(),
    "enrollment_end": course.enrollment_end and course.enrollment_end.isoformat(),
    "languages": [course.language or settings.LANGUAGE_CODE],
    }

    signature = hmac.new(
    setting.COURSE_HOOK["secret"].encode("utf-8"),
    msg=json.dumps(data).encode("utf-8"),
    digestmod=hashlib.sha256,
    ).hexdigest()

    response = requests.post(
    setting.COURSE_HOOK["url"],
    json=data,
    headers={"Authorization": "SIG-HMAC-SHA256 {:s}".format(signature)},
    )

    Thanks to the signal emitted in OpenEdX, this function can then be triggered each time a course is modified and published:

    -
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    +
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    \ No newline at end of file diff --git a/docs/2.21.0/tls-connection/index.html b/docs/2.21.0/tls-connection/index.html index 29713dd746..ef3dd363c7 100644 --- a/docs/2.21.0/tls-connection/index.html +++ b/docs/2.21.0/tls-connection/index.html @@ -2,10 +2,10 @@ - -Connecting Richie and OpenEdX over TLS for development | Richie - - + +Connecting Richie and OpenEdX over TLS for development | Richie + +
    Version: 2.21.0

    Connecting Richie and OpenEdX over TLS for development

    Purpose

    @@ -68,6 +68,6 @@

    $ make run-ssl

    Of course, you can still run apps without ssl by using:

    -
    $ make run
    +
    $ make run
    \ No newline at end of file diff --git a/docs/2.21.0/web-analytics/index.html b/docs/2.21.0/web-analytics/index.html index 85a7383a93..52379da4a1 100644 --- a/docs/2.21.0/web-analytics/index.html +++ b/docs/2.21.0/web-analytics/index.html @@ -2,13 +2,13 @@ - -Add web analytics to your site | Richie - - + +Add web analytics to your site | Richie + + -
    Version: 2.21.0

    Add web analytics to your site

    Richie has native support to Google Universal Analytics and Google Tag Manager Web Analytics solutions. +

    Version: 2.21.0

    Add web analytics to your site

    Richie has native support to Google Universal Analytics and Google Tag Manager Web Analytics solutions. The purpose of this file is to explain how you can enable one of the supported Web Analytics providers and how you can extend Richie with an alternative solution.

    Google Universal Analytics

    @@ -78,6 +78,6 @@

    +of src/frontend/js/utils/api/web-analytics/google_universal_analytics.ts and change the src/frontend/js/utils/api/web-analytics/index.ts file to include that newer provider.

    \ No newline at end of file diff --git a/docs/2.21.1/accessibility-testing/index.html b/docs/2.21.1/accessibility-testing/index.html index fbc9ed53c4..ad086a4b72 100644 --- a/docs/2.21.1/accessibility-testing/index.html +++ b/docs/2.21.1/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.21.1

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.21.1

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems on any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.21.1/api/course-run-synchronization-api/index.html b/docs/2.21.1/api/course-run-synchronization-api/index.html index df2ced7573..8c02ec41e0 100644 --- a/docs/2.21.1/api/course-run-synchronization-api/index.html +++ b/docs/2.21.1/api/course-run-synchronization-api/index.html @@ -2,10 +2,10 @@ - -Course run synchronization API | Richie - - + +Course run synchronization API | Richie + +
    Version: 2.21.1

    Course run synchronization API

    API endpoint allowing remote systems to synchronize their course runs with a Richie instance.

    @@ -52,6 +52,6 @@

    +
    \ No newline at end of file diff --git a/docs/2.21.1/building-the-frontend/index.html b/docs/2.21.1/building-the-frontend/index.html index 22262197e4..b004a33bdb 100644 --- a/docs/2.21.1/building-the-frontend/index.html +++ b/docs/2.21.1/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.21.1

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.21.1

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.21.1/contributing-guide/index.html b/docs/2.21.1/contributing-guide/index.html index 52df19650d..6772509070 100644 --- a/docs/2.21.1/contributing-guide/index.html +++ b/docs/2.21.1/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.21.1

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.21.1

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.21.1/cookiecutter/index.html b/docs/2.21.1/cookiecutter/index.html index 3df0065c5f..cc8bd4123d 100644 --- a/docs/2.21.1/cookiecutter/index.html +++ b/docs/2.21.1/cookiecutter/index.html @@ -2,13 +2,13 @@ - -Start your own site | Richie - - + +Start your own site | Richie + + -
    Version: 2.21.1

    Start your own site

    We use Cookiecutter to help you +

    Version: 2.21.1

    Start your own site

    We use Cookiecutter to help you set up a production-ready learning portal website based on Richie in seconds.

    Run Cookiecutter

    @@ -73,6 +73,6 @@

    cookiecutter --overwrite-if-exists gh:openfun/richie --directory=cookiecutter

    Help us improve this project

    After starting your project, please submit an issue let us know how it went and -what other features we should add to make it better.

    +what other features we should add to make it better.

    \ No newline at end of file diff --git a/docs/2.21.1/css-guidelines/index.html b/docs/2.21.1/css-guidelines/index.html index adc3c1b9ce..632fb64eae 100644 --- a/docs/2.21.1/css-guidelines/index.html +++ b/docs/2.21.1/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.21.1

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.21.1

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.21.1/discover/index.html b/docs/2.21.1/discover/index.html index 15a5698088..ca934efffb 100644 --- a/docs/2.21.1/discover/index.html +++ b/docs/2.21.1/discover/index.html @@ -2,13 +2,13 @@ - -Discover Richie | Richie - - + +Discover Richie | Richie + + -
    Version: 2.21.1

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online +

    Version: 2.21.1

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online courses and MOOCs.

    However, if you need to build a complete website with flexible content to aggregate your courses, in several languages and from different sources, you will soon need a CMS.

    @@ -51,6 +51,6 @@

    Start yo
  • override some css rules or rebuild the whole css with your own variables and customizations,
  • add any DjangoCMS plugin or feature,
  • add any Django third-party application.
  • -

    +
    \ No newline at end of file diff --git a/docs/2.21.1/displaying-connection-status/index.html b/docs/2.21.1/displaying-connection-status/index.html index 82e412cc7c..4b64d92adf 100644 --- a/docs/2.21.1/displaying-connection-status/index.html +++ b/docs/2.21.1/displaying-connection-status/index.html @@ -2,10 +2,10 @@ - -Displaying OpenEdX connection status in Richie | Richie - - + +Displaying OpenEdX connection status in Richie | Richie + + +
    \ No newline at end of file diff --git a/docs/2.21.1/django-react-interop/index.html b/docs/2.21.1/django-react-interop/index.html index 7de1c75b62..f4db4d4f8f 100644 --- a/docs/2.21.1/django-react-interop/index.html +++ b/docs/2.21.1/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.21.1

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.21.1

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -64,6 +64,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.21.1/docker-development/index.html b/docs/2.21.1/docker-development/index.html index 2cf3b858db..b65aef1e17 100644 --- a/docs/2.21.1/docker-development/index.html +++ b/docs/2.21.1/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.21.1

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.21.1

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.21.1/filters-customization/index.html b/docs/2.21.1/filters-customization/index.html index 4e9e13feb9..443def18ea 100644 --- a/docs/2.21.1/filters-customization/index.html +++ b/docs/2.21.1/filters-customization/index.html @@ -2,13 +2,13 @@ - -Customizing search filters | Richie - - + +Customizing search filters | Richie + + -
    Version: 2.21.1

    Customizing search filters

    You may want to customize the filters on the left side bar of the search page.

    +
    Version: 2.21.1

    Customizing search filters

    You may want to customize the filters on the left side bar of the search page.

    Richie makes it easy to choose which filters you want to display among the existing filters and in which order. You can also configure the existing filters to change their title or the way they behave. Lastly, you can completely override a filter or create your own custom filter @@ -88,6 +88,6 @@

    opening an issue!

    +opening an issue!

    \ No newline at end of file diff --git a/docs/2.21.1/frontend-overrides/index.html b/docs/2.21.1/frontend-overrides/index.html index feab15bd8e..8a353dfaee 100644 --- a/docs/2.21.1/frontend-overrides/index.html +++ b/docs/2.21.1/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.21.1

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.21.1

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.21.1/installation/index.html b/docs/2.21.1/installation/index.html index 42ab7f73a6..a2cdbfe441 100644 --- a/docs/2.21.1/installation/index.html +++ b/docs/2.21.1/installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie for development | Richie - - + +Installing Richie for development | Richie + + -
    Version: 2.21.1

    Installing Richie for development

    Richie is a container-native application but can also be installed +

    +https://www.nau.edu.pt.

    \ No newline at end of file diff --git a/docs/2.21.1/internationalization/index.html b/docs/2.21.1/internationalization/index.html index 66a645a63d..66ea973e48 100644 --- a/docs/2.21.1/internationalization/index.html +++ b/docs/2.21.1/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.21.1

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.21.1

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.21.1/joanie-connection/index.html b/docs/2.21.1/joanie-connection/index.html index 4852fc6de9..2cfb2d3984 100644 --- a/docs/2.21.1/joanie-connection/index.html +++ b/docs/2.21.1/joanie-connection/index.html @@ -2,10 +2,10 @@ - -Joanie Connection | Richie - - + +Joanie Connection | Richie + +
    Version: 2.21.1

    Joanie Connection

    Joanie delivers an API able to manage course @@ -90,6 +90,6 @@

    Lifet its lifetime is 5 minutes by default.

    Technical support

    If you encounter an issue with this documentation, please -open an issue on our repository.

    +open an issue on our repository.

    \ No newline at end of file diff --git a/docs/2.21.1/lms-backends/index.html b/docs/2.21.1/lms-backends/index.html index 3e6c9dc5fa..628357ec23 100644 --- a/docs/2.21.1/lms-backends/index.html +++ b/docs/2.21.1/lms-backends/index.html @@ -2,10 +2,10 @@ - -Configuring LMS Backends | Richie - - + +Configuring LMS Backends | Richie + +
    Version: 2.21.1

    Configuring LMS Backends

    Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless @@ -115,6 +115,6 @@

    Technical

    If you encounter an issue with this documentation or the backends included in Richie, please open an issue on our repository.

    If you need a custom backend, you can submit a PR or -open an issue and we will consider adding it.

    +open an issue and we will consider adding it.

    \ No newline at end of file diff --git a/docs/2.21.1/lms-connection/index.html b/docs/2.21.1/lms-connection/index.html index ec887173e3..d7aad1b8ca 100644 --- a/docs/2.21.1/lms-connection/index.html +++ b/docs/2.21.1/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with one or more LMS | Richie - - + +Connecting Richie with one or more LMS | Richie + + -
    Version: 2.21.1

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    +
    Version: 2.21.1

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    Richie can be connected to an LMS in several ways, ranging from SSO to a fully integrated seamless experience.

    As of today, each approach has been implemented for OpenEdX but the same could be done for @@ -63,6 +63,6 @@

    Development

    If you want to activate seamless enrollment locally for development, you will need to set up TLS domains for both Richie and OpenEdX. To do this, head over to our -guide on setting-up TLS connections for Richie and OpenEdX.

    +guide on setting-up TLS connections for Richie and OpenEdX.

    \ No newline at end of file diff --git a/docs/2.21.1/native-installation/index.html b/docs/2.21.1/native-installation/index.html index 01b1011e03..993f55b0ff 100644 --- a/docs/2.21.1/native-installation/index.html +++ b/docs/2.21.1/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.21.1

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.21.1

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native installation instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.21.1/synchronizing-course-runs/index.html b/docs/2.21.1/synchronizing-course-runs/index.html index 870f634555..625ee1d352 100644 --- a/docs/2.21.1/synchronizing-course-runs/index.html +++ b/docs/2.21.1/synchronizing-course-runs/index.html @@ -2,10 +2,10 @@ - -Synchronizing course runs between Richie and OpenEdX | Richie - - + +Synchronizing course runs between Richie and OpenEdX | Richie + +
    Version: 2.21.1

    Synchronizing course runs between Richie and OpenEdX

    Richie can receive automatic course runs updates on a dedicated API endpoint.

    @@ -51,6 +51,6 @@

    import hashlib
    import hmac
    import json

    from django.conf import settings

    from microsite_configuration import microsite
    import requests
    from xmodule.modulestore.django import modulestore


    def update_course(course_key, *args, **kwargs):
    """Synchronize an OpenEdX course, identified by its course key, with a Richie instance."""
    course = modulestore().get_course(course_key)
    edxapp_domain = microsite.get_value("site_domain", settings.LMS_BASE)

    data = {
    "resource_link": "https://{:s}/courses/{!s}/info".format(
    edxapp_domain, course_key
    ),
    "start": course.start and course.start.isoformat(),
    "end": course.end and course.end.isoformat(),
    "enrollment_start": course.enrollment_start and course.enrollment_start.isoformat(),
    "enrollment_end": course.enrollment_end and course.enrollment_end.isoformat(),
    "languages": [course.language or settings.LANGUAGE_CODE],
    }

    signature = hmac.new(
    setting.COURSE_HOOK["secret"].encode("utf-8"),
    msg=json.dumps(data).encode("utf-8"),
    digestmod=hashlib.sha256,
    ).hexdigest()

    response = requests.post(
    setting.COURSE_HOOK["url"],
    json=data,
    headers={"Authorization": "SIG-HMAC-SHA256 {:s}".format(signature)},
    )

    Thanks to the signal emitted in OpenEdX, this function can then be triggered each time a course is modified and published:

    -
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    +
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    \ No newline at end of file diff --git a/docs/2.21.1/tls-connection/index.html b/docs/2.21.1/tls-connection/index.html index 7529d37e8b..b04122b613 100644 --- a/docs/2.21.1/tls-connection/index.html +++ b/docs/2.21.1/tls-connection/index.html @@ -2,10 +2,10 @@ - -Connecting Richie and OpenEdX over TLS for development | Richie - - + +Connecting Richie and OpenEdX over TLS for development | Richie + +
    Version: 2.21.1

    Connecting Richie and OpenEdX over TLS for development

    Purpose

    @@ -68,6 +68,6 @@

    $ make run-ssl

    Of course, you can still run apps without ssl by using:

    -
    $ make run
    +
    $ make run
    \ No newline at end of file diff --git a/docs/2.21.1/web-analytics/index.html b/docs/2.21.1/web-analytics/index.html index f1c792545a..ef2325a6b6 100644 --- a/docs/2.21.1/web-analytics/index.html +++ b/docs/2.21.1/web-analytics/index.html @@ -2,13 +2,13 @@ - -Add web analytics to your site | Richie - - + +Add web analytics to your site | Richie + + -
    Version: 2.21.1

    Add web analytics to your site

    Richie has native support to Google Universal Analytics and Google Tag Manager Web Analytics solutions. +

    Version: 2.21.1

    Add web analytics to your site

    Richie has native support to Google Universal Analytics and Google Tag Manager Web Analytics solutions. The purpose of this file is to explain how you can enable one of the supported Web Analytics providers and how you can extend Richie with an alternative solution.

    Google Universal Analytics

    @@ -78,6 +78,6 @@

    +of src/frontend/js/utils/api/web-analytics/google_universal_analytics.ts and change the src/frontend/js/utils/api/web-analytics/index.ts file to include that newer provider.

    \ No newline at end of file diff --git a/docs/2.22.0/accessibility-testing/index.html b/docs/2.22.0/accessibility-testing/index.html index cf85ffc603..108dfb5e94 100644 --- a/docs/2.22.0/accessibility-testing/index.html +++ b/docs/2.22.0/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.22.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.22.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems on any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.22.0/api/course-run-synchronization-api/index.html b/docs/2.22.0/api/course-run-synchronization-api/index.html index ded5676558..74f03124c7 100644 --- a/docs/2.22.0/api/course-run-synchronization-api/index.html +++ b/docs/2.22.0/api/course-run-synchronization-api/index.html @@ -2,10 +2,10 @@ - -Course run synchronization API | Richie - - + +Course run synchronization API | Richie + +
    Version: 2.22.0

    Course run synchronization API

    API endpoint allowing remote systems to synchronize their course runs with a Richie instance.

    @@ -52,6 +52,6 @@

    +
    \ No newline at end of file diff --git a/docs/2.22.0/building-the-frontend/index.html b/docs/2.22.0/building-the-frontend/index.html index 79f510b013..46808a64cd 100644 --- a/docs/2.22.0/building-the-frontend/index.html +++ b/docs/2.22.0/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.22.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.22.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.22.0/contributing-guide/index.html b/docs/2.22.0/contributing-guide/index.html index f234a99c0d..c6b0cc66ca 100644 --- a/docs/2.22.0/contributing-guide/index.html +++ b/docs/2.22.0/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.22.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.22.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.22.0/cookiecutter/index.html b/docs/2.22.0/cookiecutter/index.html index 41d2792daa..77c56eb0f3 100644 --- a/docs/2.22.0/cookiecutter/index.html +++ b/docs/2.22.0/cookiecutter/index.html @@ -2,13 +2,13 @@ - -Start your own site | Richie - - + +Start your own site | Richie + + -
    Version: 2.22.0

    Start your own site

    We use Cookiecutter to help you +

    Version: 2.22.0

    Start your own site

    We use Cookiecutter to help you set up a production-ready learning portal website based on Richie in seconds.

    Run Cookiecutter

    @@ -73,6 +73,6 @@

    cookiecutter --overwrite-if-exists gh:openfun/richie --directory=cookiecutter

    Help us improve this project

    After starting your project, please submit an issue let us know how it went and -what other features we should add to make it better.

    +what other features we should add to make it better.

    \ No newline at end of file diff --git a/docs/2.22.0/css-guidelines/index.html b/docs/2.22.0/css-guidelines/index.html index ff38dbe587..1419136cd0 100644 --- a/docs/2.22.0/css-guidelines/index.html +++ b/docs/2.22.0/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.22.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.22.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.22.0/discover/index.html b/docs/2.22.0/discover/index.html index 30efa458e6..49173549d1 100644 --- a/docs/2.22.0/discover/index.html +++ b/docs/2.22.0/discover/index.html @@ -2,13 +2,13 @@ - -Discover Richie | Richie - - + +Discover Richie | Richie + + -
    Version: 2.22.0

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online +

    Version: 2.22.0

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online courses and MOOCs.

    However, if you need to build a complete website with flexible content to aggregate your courses, in several languages and from different sources, you will soon need a CMS.

    @@ -51,6 +51,6 @@

    Start yo
  • override some css rules or rebuild the whole css with your own variables and customizations,
  • add any DjangoCMS plugin or feature,
  • add any Django third-party application.
  • -

    +
    \ No newline at end of file diff --git a/docs/2.22.0/displaying-connection-status/index.html b/docs/2.22.0/displaying-connection-status/index.html index 4b6f30de98..4ed59b7c63 100644 --- a/docs/2.22.0/displaying-connection-status/index.html +++ b/docs/2.22.0/displaying-connection-status/index.html @@ -2,10 +2,10 @@ - -Displaying OpenEdX connection status in Richie | Richie - - + +Displaying OpenEdX connection status in Richie | Richie + + +
    \ No newline at end of file diff --git a/docs/2.22.0/django-react-interop/index.html b/docs/2.22.0/django-react-interop/index.html index 64a5bcd4e6..4955a75258 100644 --- a/docs/2.22.0/django-react-interop/index.html +++ b/docs/2.22.0/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.22.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.22.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -64,6 +64,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.22.0/docker-development/index.html b/docs/2.22.0/docker-development/index.html index c540d75cac..583f1cd9ff 100644 --- a/docs/2.22.0/docker-development/index.html +++ b/docs/2.22.0/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.22.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.22.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.22.0/filters-customization/index.html b/docs/2.22.0/filters-customization/index.html index 2f74d0826f..44c755f0b3 100644 --- a/docs/2.22.0/filters-customization/index.html +++ b/docs/2.22.0/filters-customization/index.html @@ -2,13 +2,13 @@ - -Customizing search filters | Richie - - + +Customizing search filters | Richie + + -
    Version: 2.22.0

    Customizing search filters

    You may want to customize the filters on the left side bar of the search page.

    +
    Version: 2.22.0

    Customizing search filters

    You may want to customize the filters on the left side bar of the search page.

    Richie makes it easy to choose which filters you want to display among the existing filters and in which order. You can also configure the existing filters to change their title or the way they behave. Lastly, you can completely override a filter or create your own custom filter @@ -88,6 +88,6 @@

    opening an issue!

    +opening an issue!

    \ No newline at end of file diff --git a/docs/2.22.0/frontend-overrides/index.html b/docs/2.22.0/frontend-overrides/index.html index a2b2e3cdd8..ef3cfe12b4 100644 --- a/docs/2.22.0/frontend-overrides/index.html +++ b/docs/2.22.0/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.22.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.22.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.22.0/installation/index.html b/docs/2.22.0/installation/index.html index f8ca996956..8c1aefef65 100644 --- a/docs/2.22.0/installation/index.html +++ b/docs/2.22.0/installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie for development | Richie - - + +Installing Richie for development | Richie + + -
    Version: 2.22.0

    Installing Richie for development

    Richie is a container-native application but can also be installed +

    +https://www.nau.edu.pt.

    \ No newline at end of file diff --git a/docs/2.22.0/internationalization/index.html b/docs/2.22.0/internationalization/index.html index 596610e47c..a60413b19d 100644 --- a/docs/2.22.0/internationalization/index.html +++ b/docs/2.22.0/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.22.0

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.22.0

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.22.0/joanie-connection/index.html b/docs/2.22.0/joanie-connection/index.html index 8f0231359f..052ddc5471 100644 --- a/docs/2.22.0/joanie-connection/index.html +++ b/docs/2.22.0/joanie-connection/index.html @@ -2,10 +2,10 @@ - -Joanie Connection | Richie - - + +Joanie Connection | Richie + +
    Version: 2.22.0

    Joanie Connection

    Joanie delivers an API able to manage course @@ -90,6 +90,6 @@

    Lifet its lifetime is 5 minutes by default.

    Technical support

    If you encounter an issue with this documentation, please -open an issue on our repository.

    +open an issue on our repository.

    \ No newline at end of file diff --git a/docs/2.22.0/lms-backends/index.html b/docs/2.22.0/lms-backends/index.html index 51f4bea199..74c6a777fd 100644 --- a/docs/2.22.0/lms-backends/index.html +++ b/docs/2.22.0/lms-backends/index.html @@ -2,10 +2,10 @@ - -Configuring LMS Backends | Richie - - + +Configuring LMS Backends | Richie + +
    Version: 2.22.0

    Configuring LMS Backends

    Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless @@ -115,6 +115,6 @@

    Technical

    If you encounter an issue with this documentation or the backends included in Richie, please open an issue on our repository.

    If you need a custom backend, you can submit a PR or -open an issue and we will consider adding it.

    +open an issue and we will consider adding it.

    \ No newline at end of file diff --git a/docs/2.22.0/lms-connection/index.html b/docs/2.22.0/lms-connection/index.html index aefde5f0f0..08bde9271c 100644 --- a/docs/2.22.0/lms-connection/index.html +++ b/docs/2.22.0/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with one or more LMS | Richie - - + +Connecting Richie with one or more LMS | Richie + + -
    Version: 2.22.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    +
    Version: 2.22.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    Richie can be connected to an LMS in several ways, ranging from SSO to a fully integrated seamless experience.

    As of today, each approach has been implemented for OpenEdX but the same could be done for @@ -63,6 +63,6 @@

    Development

    If you want to activate seamless enrollment locally for development, you will need to set up TLS domains for both Richie and OpenEdX. To do this, head over to our -guide on setting-up TLS connections for Richie and OpenEdX.

    +guide on setting-up TLS connections for Richie and OpenEdX.

    \ No newline at end of file diff --git a/docs/2.22.0/native-installation/index.html b/docs/2.22.0/native-installation/index.html index d4796a95c7..cf583478f0 100644 --- a/docs/2.22.0/native-installation/index.html +++ b/docs/2.22.0/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.22.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.22.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native installation instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.22.0/synchronizing-course-runs/index.html b/docs/2.22.0/synchronizing-course-runs/index.html index 4825fb6479..ebdb55fda5 100644 --- a/docs/2.22.0/synchronizing-course-runs/index.html +++ b/docs/2.22.0/synchronizing-course-runs/index.html @@ -2,10 +2,10 @@ - -Synchronizing course runs between Richie and OpenEdX | Richie - - + +Synchronizing course runs between Richie and OpenEdX | Richie + +
    Version: 2.22.0

    Synchronizing course runs between Richie and OpenEdX

    Richie can receive automatic course runs updates on a dedicated API endpoint.

    @@ -51,6 +51,6 @@

    import hashlib
    import hmac
    import json

    from django.conf import settings

    from microsite_configuration import microsite
    import requests
    from xmodule.modulestore.django import modulestore


    def update_course(course_key, *args, **kwargs):
    """Synchronize an OpenEdX course, identified by its course key, with a Richie instance."""
    course = modulestore().get_course(course_key)
    edxapp_domain = microsite.get_value("site_domain", settings.LMS_BASE)

    data = {
    "resource_link": "https://{:s}/courses/{!s}/info".format(
    edxapp_domain, course_key
    ),
    "start": course.start and course.start.isoformat(),
    "end": course.end and course.end.isoformat(),
    "enrollment_start": course.enrollment_start and course.enrollment_start.isoformat(),
    "enrollment_end": course.enrollment_end and course.enrollment_end.isoformat(),
    "languages": [course.language or settings.LANGUAGE_CODE],
    }

    signature = hmac.new(
    setting.COURSE_HOOK["secret"].encode("utf-8"),
    msg=json.dumps(data).encode("utf-8"),
    digestmod=hashlib.sha256,
    ).hexdigest()

    response = requests.post(
    setting.COURSE_HOOK["url"],
    json=data,
    headers={"Authorization": "SIG-HMAC-SHA256 {:s}".format(signature)},
    )

    Thanks to the signal emitted in OpenEdX, this function can then be triggered each time a course is modified and published:

    -
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    +
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    \ No newline at end of file diff --git a/docs/2.22.0/tls-connection/index.html b/docs/2.22.0/tls-connection/index.html index 94320713f5..87aa48bb76 100644 --- a/docs/2.22.0/tls-connection/index.html +++ b/docs/2.22.0/tls-connection/index.html @@ -2,10 +2,10 @@ - -Connecting Richie and OpenEdX over TLS for development | Richie - - + +Connecting Richie and OpenEdX over TLS for development | Richie + +
    Version: 2.22.0

    Connecting Richie and OpenEdX over TLS for development

    Purpose

    @@ -68,6 +68,6 @@

    $ make run-ssl

    Of course, you can still run apps without ssl by using:

    -
    $ make run
    +
    $ make run
    \ No newline at end of file diff --git a/docs/2.22.0/web-analytics/index.html b/docs/2.22.0/web-analytics/index.html index 760ca309c3..d277d8918c 100644 --- a/docs/2.22.0/web-analytics/index.html +++ b/docs/2.22.0/web-analytics/index.html @@ -2,13 +2,13 @@ - -Add web analytics to your site | Richie - - + +Add web analytics to your site | Richie + + -
    Version: 2.22.0

    Add web analytics to your site

    Richie has native support to Google Universal Analytics and Google Tag Manager Web Analytics solutions. +

    Version: 2.22.0

    Add web analytics to your site

    Richie has native support to Google Universal Analytics and Google Tag Manager Web Analytics solutions. The purpose of this file is to explain how you can enable one of the supported Web Analytics providers and how you can extend Richie with an alternative solution.

    Google Universal Analytics

    @@ -78,6 +78,6 @@

    +of src/frontend/js/utils/api/web-analytics/google_universal_analytics.ts and change the src/frontend/js/utils/api/web-analytics/index.ts file to include that newer provider.

    \ No newline at end of file diff --git a/docs/2.23.0/accessibility-testing/index.html b/docs/2.23.0/accessibility-testing/index.html index c79411a60f..4826af4e51 100644 --- a/docs/2.23.0/accessibility-testing/index.html +++ b/docs/2.23.0/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.23.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.23.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems on any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.23.0/api/course-run-synchronization-api/index.html b/docs/2.23.0/api/course-run-synchronization-api/index.html index 2082e799e4..34e241dcfc 100644 --- a/docs/2.23.0/api/course-run-synchronization-api/index.html +++ b/docs/2.23.0/api/course-run-synchronization-api/index.html @@ -2,10 +2,10 @@ - -Course run synchronization API | Richie - - + +Course run synchronization API | Richie + +
    Version: 2.23.0

    Course run synchronization API

    API endpoint allowing remote systems to synchronize their course runs with a Richie instance.

    @@ -52,6 +52,6 @@

    +
    \ No newline at end of file diff --git a/docs/2.23.0/building-the-frontend/index.html b/docs/2.23.0/building-the-frontend/index.html index e9f3a605b3..aab80483d3 100644 --- a/docs/2.23.0/building-the-frontend/index.html +++ b/docs/2.23.0/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.23.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.23.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.23.0/contributing-guide/index.html b/docs/2.23.0/contributing-guide/index.html index 9087060352..014b9e26ff 100644 --- a/docs/2.23.0/contributing-guide/index.html +++ b/docs/2.23.0/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.23.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.23.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.23.0/cookiecutter/index.html b/docs/2.23.0/cookiecutter/index.html index 0fe27bb4e2..93585e5724 100644 --- a/docs/2.23.0/cookiecutter/index.html +++ b/docs/2.23.0/cookiecutter/index.html @@ -2,13 +2,13 @@ - -Start your own site | Richie - - + +Start your own site | Richie + + -
    Version: 2.23.0

    Start your own site

    We use Cookiecutter to help you +

    Version: 2.23.0

    Start your own site

    We use Cookiecutter to help you set up a production-ready learning portal website based on Richie in seconds.

    Run Cookiecutter

    @@ -73,6 +73,6 @@

    cookiecutter --overwrite-if-exists gh:openfun/richie --directory=cookiecutter

    Help us improve this project

    After starting your project, please submit an issue let us know how it went and -what other features we should add to make it better.

    +what other features we should add to make it better.

    \ No newline at end of file diff --git a/docs/2.23.0/css-guidelines/index.html b/docs/2.23.0/css-guidelines/index.html index ce10fc5483..1348007e2a 100644 --- a/docs/2.23.0/css-guidelines/index.html +++ b/docs/2.23.0/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.23.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.23.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.23.0/discover/index.html b/docs/2.23.0/discover/index.html index 360f7643a4..ee3ddd927f 100644 --- a/docs/2.23.0/discover/index.html +++ b/docs/2.23.0/discover/index.html @@ -2,13 +2,13 @@ - -Discover Richie | Richie - - + +Discover Richie | Richie + + -
    Version: 2.23.0

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online +

    Version: 2.23.0

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online courses and MOOCs.

    However, if you need to build a complete website with flexible content to aggregate your courses, in several languages and from different sources, you will soon need a CMS.

    @@ -51,6 +51,6 @@

    Start yo
  • override some css rules or rebuild the whole css with your own variables and customizations,
  • add any DjangoCMS plugin or feature,
  • add any Django third-party application.
  • -

    +
    \ No newline at end of file diff --git a/docs/2.23.0/displaying-connection-status/index.html b/docs/2.23.0/displaying-connection-status/index.html index b836206b79..83a7da77fd 100644 --- a/docs/2.23.0/displaying-connection-status/index.html +++ b/docs/2.23.0/displaying-connection-status/index.html @@ -2,10 +2,10 @@ - -Displaying OpenEdX connection status in Richie | Richie - - + +Displaying OpenEdX connection status in Richie | Richie + + +
    \ No newline at end of file diff --git a/docs/2.23.0/django-react-interop/index.html b/docs/2.23.0/django-react-interop/index.html index 9af6dbfcbd..c84aa5326e 100644 --- a/docs/2.23.0/django-react-interop/index.html +++ b/docs/2.23.0/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.23.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.23.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -64,6 +64,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.23.0/docker-development/index.html b/docs/2.23.0/docker-development/index.html index 06ebe7b9b1..e3c97d2cea 100644 --- a/docs/2.23.0/docker-development/index.html +++ b/docs/2.23.0/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.23.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.23.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.23.0/filters-customization/index.html b/docs/2.23.0/filters-customization/index.html index 67d42652cd..b733dec62a 100644 --- a/docs/2.23.0/filters-customization/index.html +++ b/docs/2.23.0/filters-customization/index.html @@ -2,13 +2,13 @@ - -Customizing search filters | Richie - - + +Customizing search filters | Richie + + -
    Version: 2.23.0

    Customizing search filters

    You may want to customize the filters on the left side bar of the search page.

    +
    Version: 2.23.0

    Customizing search filters

    You may want to customize the filters on the left side bar of the search page.

    Richie makes it easy to choose which filters you want to display among the existing filters and in which order. You can also configure the existing filters to change their title or the way they behave. Lastly, you can completely override a filter or create your own custom filter @@ -88,6 +88,6 @@

    opening an issue!

    +opening an issue!

    \ No newline at end of file diff --git a/docs/2.23.0/frontend-overrides/index.html b/docs/2.23.0/frontend-overrides/index.html index d58ccc3798..984df8d2d9 100644 --- a/docs/2.23.0/frontend-overrides/index.html +++ b/docs/2.23.0/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.23.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.23.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.23.0/installation/index.html b/docs/2.23.0/installation/index.html index 9ab55eb3d7..a67be6c7ff 100644 --- a/docs/2.23.0/installation/index.html +++ b/docs/2.23.0/installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie for development | Richie - - + +Installing Richie for development | Richie + + -
    Version: 2.23.0

    Installing Richie for development

    Richie is a container-native application but can also be installed +

    +https://www.nau.edu.pt.

    \ No newline at end of file diff --git a/docs/2.23.0/internationalization/index.html b/docs/2.23.0/internationalization/index.html index c99d46a2e4..4e4abb3818 100644 --- a/docs/2.23.0/internationalization/index.html +++ b/docs/2.23.0/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.23.0

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.23.0

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.23.0/joanie-connection/index.html b/docs/2.23.0/joanie-connection/index.html index 8175396881..03daaa2661 100644 --- a/docs/2.23.0/joanie-connection/index.html +++ b/docs/2.23.0/joanie-connection/index.html @@ -2,10 +2,10 @@ - -Joanie Connection | Richie - - + +Joanie Connection | Richie + +
    Version: 2.23.0

    Joanie Connection

    Joanie delivers an API able to manage course @@ -90,6 +90,6 @@

    Lifet its lifetime is 5 minutes by default.

    Technical support

    If you encounter an issue with this documentation, please -open an issue on our repository.

    +open an issue on our repository.

    \ No newline at end of file diff --git a/docs/2.23.0/lms-backends/index.html b/docs/2.23.0/lms-backends/index.html index 64bdf5a947..370ec9b326 100644 --- a/docs/2.23.0/lms-backends/index.html +++ b/docs/2.23.0/lms-backends/index.html @@ -2,10 +2,10 @@ - -Configuring LMS Backends | Richie - - + +Configuring LMS Backends | Richie + +
    Version: 2.23.0

    Configuring LMS Backends

    Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless @@ -115,6 +115,6 @@

    Technical

    If you encounter an issue with this documentation or the backends included in Richie, please open an issue on our repository.

    If you need a custom backend, you can submit a PR or -open an issue and we will consider adding it.

    +open an issue and we will consider adding it.

    \ No newline at end of file diff --git a/docs/2.23.0/lms-connection/index.html b/docs/2.23.0/lms-connection/index.html index 1e6fad4b0d..4744c254cc 100644 --- a/docs/2.23.0/lms-connection/index.html +++ b/docs/2.23.0/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with one or more LMS | Richie - - + +Connecting Richie with one or more LMS | Richie + + -
    Version: 2.23.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    +
    Version: 2.23.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    Richie can be connected to an LMS in several ways, ranging from SSO to a fully integrated seamless experience.

    As of today, each approach has been implemented for OpenEdX but the same could be done for @@ -63,6 +63,6 @@

    Development

    If you want to activate seamless enrollment locally for development, you will need to set up TLS domains for both Richie and OpenEdX. To do this, head over to our -guide on setting-up TLS connections for Richie and OpenEdX.

    +guide on setting-up TLS connections for Richie and OpenEdX.

    \ No newline at end of file diff --git a/docs/2.23.0/native-installation/index.html b/docs/2.23.0/native-installation/index.html index 35b5b33561..1b3a30676e 100644 --- a/docs/2.23.0/native-installation/index.html +++ b/docs/2.23.0/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.23.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.23.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native installation instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.23.0/synchronizing-course-runs/index.html b/docs/2.23.0/synchronizing-course-runs/index.html index b671e00d88..113d60d97c 100644 --- a/docs/2.23.0/synchronizing-course-runs/index.html +++ b/docs/2.23.0/synchronizing-course-runs/index.html @@ -2,10 +2,10 @@ - -Synchronizing course runs between Richie and OpenEdX | Richie - - + +Synchronizing course runs between Richie and OpenEdX | Richie + +
    Version: 2.23.0

    Synchronizing course runs between Richie and OpenEdX

    Richie can receive automatic course runs updates on a dedicated API endpoint.

    @@ -51,6 +51,6 @@

    import hashlib
    import hmac
    import json

    from django.conf import settings

    from microsite_configuration import microsite
    import requests
    from xmodule.modulestore.django import modulestore


    def update_course(course_key, *args, **kwargs):
    """Synchronize an OpenEdX course, identified by its course key, with a Richie instance."""
    course = modulestore().get_course(course_key)
    edxapp_domain = microsite.get_value("site_domain", settings.LMS_BASE)

    data = {
    "resource_link": "https://{:s}/courses/{!s}/info".format(
    edxapp_domain, course_key
    ),
    "start": course.start and course.start.isoformat(),
    "end": course.end and course.end.isoformat(),
    "enrollment_start": course.enrollment_start and course.enrollment_start.isoformat(),
    "enrollment_end": course.enrollment_end and course.enrollment_end.isoformat(),
    "languages": [course.language or settings.LANGUAGE_CODE],
    }

    signature = hmac.new(
    setting.COURSE_HOOK["secret"].encode("utf-8"),
    msg=json.dumps(data).encode("utf-8"),
    digestmod=hashlib.sha256,
    ).hexdigest()

    response = requests.post(
    setting.COURSE_HOOK["url"],
    json=data,
    headers={"Authorization": "SIG-HMAC-SHA256 {:s}".format(signature)},
    )

    Thanks to the signal emitted in OpenEdX, this function can then be triggered each time a course is modified and published:

    -
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    +
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    \ No newline at end of file diff --git a/docs/2.23.0/tls-connection/index.html b/docs/2.23.0/tls-connection/index.html index 21050001ae..a82603976c 100644 --- a/docs/2.23.0/tls-connection/index.html +++ b/docs/2.23.0/tls-connection/index.html @@ -2,10 +2,10 @@ - -Connecting Richie and OpenEdX over TLS for development | Richie - - + +Connecting Richie and OpenEdX over TLS for development | Richie + +
    Version: 2.23.0

    Connecting Richie and OpenEdX over TLS for development

    Purpose

    @@ -68,6 +68,6 @@

    $ make run-ssl

    Of course, you can still run apps without ssl by using:

    -
    $ make run
    +
    $ make run
    \ No newline at end of file diff --git a/docs/2.23.0/web-analytics/index.html b/docs/2.23.0/web-analytics/index.html index 0bcea9a94d..4fc464141e 100644 --- a/docs/2.23.0/web-analytics/index.html +++ b/docs/2.23.0/web-analytics/index.html @@ -2,13 +2,13 @@ - -Add web analytics to your site | Richie - - + +Add web analytics to your site | Richie + + -
    Version: 2.23.0

    Add web analytics to your site

    Richie has native support to Google Universal Analytics and Google Tag Manager Web Analytics solutions. +

    Version: 2.23.0

    Add web analytics to your site

    Richie has native support to Google Universal Analytics and Google Tag Manager Web Analytics solutions. The purpose of this file is to explain how you can enable one of the supported Web Analytics providers and how you can extend Richie with an alternative solution.

    Google Universal Analytics

    @@ -78,6 +78,6 @@

    +of src/frontend/js/utils/api/web-analytics/google_universal_analytics.ts and change the src/frontend/js/utils/api/web-analytics/index.ts file to include that newer provider.

    \ No newline at end of file diff --git a/docs/2.24.0/accessibility-testing/index.html b/docs/2.24.0/accessibility-testing/index.html index 710944f325..d8713cade3 100644 --- a/docs/2.24.0/accessibility-testing/index.html +++ b/docs/2.24.0/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.24.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.24.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems on any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.24.0/api/course-run-synchronization-api/index.html b/docs/2.24.0/api/course-run-synchronization-api/index.html index 84c5306b09..9d09d456c2 100644 --- a/docs/2.24.0/api/course-run-synchronization-api/index.html +++ b/docs/2.24.0/api/course-run-synchronization-api/index.html @@ -2,10 +2,10 @@ - -Course run synchronization API | Richie - - + +Course run synchronization API | Richie + +
    Version: 2.24.0

    Course run synchronization API

    API endpoint allowing remote systems to synchronize their course runs with a Richie instance.

    @@ -52,6 +52,6 @@

    +
    \ No newline at end of file diff --git a/docs/2.24.0/building-the-frontend/index.html b/docs/2.24.0/building-the-frontend/index.html index 9dcb5a33e8..0f63671edc 100644 --- a/docs/2.24.0/building-the-frontend/index.html +++ b/docs/2.24.0/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.24.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.24.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.24.0/contributing-guide/index.html b/docs/2.24.0/contributing-guide/index.html index f866dd58db..0281986237 100644 --- a/docs/2.24.0/contributing-guide/index.html +++ b/docs/2.24.0/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.24.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.24.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.24.0/cookiecutter/index.html b/docs/2.24.0/cookiecutter/index.html index 437e08cc35..0649ccd0bb 100644 --- a/docs/2.24.0/cookiecutter/index.html +++ b/docs/2.24.0/cookiecutter/index.html @@ -2,13 +2,13 @@ - -Start your own site | Richie - - + +Start your own site | Richie + + -
    Version: 2.24.0

    Start your own site

    We use Cookiecutter to help you +

    Version: 2.24.0

    Start your own site

    We use Cookiecutter to help you set up a production-ready learning portal website based on Richie in seconds.

    Run Cookiecutter

    @@ -73,6 +73,6 @@

    cookiecutter --overwrite-if-exists gh:openfun/richie --directory=cookiecutter

    Help us improve this project

    After starting your project, please submit an issue let us know how it went and -what other features we should add to make it better.

    +what other features we should add to make it better.

    \ No newline at end of file diff --git a/docs/2.24.0/css-guidelines/index.html b/docs/2.24.0/css-guidelines/index.html index ef16d477e7..92dd44b864 100644 --- a/docs/2.24.0/css-guidelines/index.html +++ b/docs/2.24.0/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.24.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.24.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.24.0/discover/index.html b/docs/2.24.0/discover/index.html index 8b71d8d6d8..04db2e33e6 100644 --- a/docs/2.24.0/discover/index.html +++ b/docs/2.24.0/discover/index.html @@ -2,13 +2,13 @@ - -Discover Richie | Richie - - + +Discover Richie | Richie + + -
    Version: 2.24.0

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online +

    Version: 2.24.0

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online courses and MOOCs.

    However, if you need to build a complete website with flexible content to aggregate your courses, in several languages and from different sources, you will soon need a CMS.

    @@ -51,6 +51,6 @@

    Start yo
  • override some css rules or rebuild the whole css with your own variables and customizations,
  • add any DjangoCMS plugin or feature,
  • add any Django third-party application.
  • -

    +
    \ No newline at end of file diff --git a/docs/2.24.0/displaying-connection-status/index.html b/docs/2.24.0/displaying-connection-status/index.html index 729e4fb11d..4732ac3d20 100644 --- a/docs/2.24.0/displaying-connection-status/index.html +++ b/docs/2.24.0/displaying-connection-status/index.html @@ -2,10 +2,10 @@ - -Displaying OpenEdX connection status in Richie | Richie - - + +Displaying OpenEdX connection status in Richie | Richie + + +
    \ No newline at end of file diff --git a/docs/2.24.0/django-react-interop/index.html b/docs/2.24.0/django-react-interop/index.html index 5a578c44f7..eb59b035ba 100644 --- a/docs/2.24.0/django-react-interop/index.html +++ b/docs/2.24.0/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.24.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.24.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -64,6 +64,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.24.0/docker-development/index.html b/docs/2.24.0/docker-development/index.html index df77bbb9d4..b7e0fcaa41 100644 --- a/docs/2.24.0/docker-development/index.html +++ b/docs/2.24.0/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.24.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.24.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.24.0/filters-customization/index.html b/docs/2.24.0/filters-customization/index.html index bb33862dad..00b3b7257c 100644 --- a/docs/2.24.0/filters-customization/index.html +++ b/docs/2.24.0/filters-customization/index.html @@ -2,13 +2,13 @@ - -Customizing search filters | Richie - - + +Customizing search filters | Richie + + -
    Version: 2.24.0

    Customizing search filters

    You may want to customize the filters on the left side bar of the search page.

    +
    Version: 2.24.0

    Customizing search filters

    You may want to customize the filters on the left side bar of the search page.

    Richie makes it easy to choose which filters you want to display among the existing filters and in which order. You can also configure the existing filters to change their title or the way they behave. Lastly, you can completely override a filter or create your own custom filter @@ -88,6 +88,6 @@

    opening an issue!

    +opening an issue!

    \ No newline at end of file diff --git a/docs/2.24.0/frontend-overrides/index.html b/docs/2.24.0/frontend-overrides/index.html index ed8f9fd2bb..b7ddd7cd31 100644 --- a/docs/2.24.0/frontend-overrides/index.html +++ b/docs/2.24.0/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.24.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.24.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.24.0/installation/index.html b/docs/2.24.0/installation/index.html index 7857d76158..6c62110d8a 100644 --- a/docs/2.24.0/installation/index.html +++ b/docs/2.24.0/installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie for development | Richie - - + +Installing Richie for development | Richie + + -
    Version: 2.24.0

    Installing Richie for development

    Richie is a container-native application but can also be installed +

    +https://www.nau.edu.pt.

    \ No newline at end of file diff --git a/docs/2.24.0/internationalization/index.html b/docs/2.24.0/internationalization/index.html index 484ecb181f..cf162e58dc 100644 --- a/docs/2.24.0/internationalization/index.html +++ b/docs/2.24.0/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.24.0

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.24.0

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.24.0/joanie-connection/index.html b/docs/2.24.0/joanie-connection/index.html index 3dccc79602..d6095b55ac 100644 --- a/docs/2.24.0/joanie-connection/index.html +++ b/docs/2.24.0/joanie-connection/index.html @@ -2,10 +2,10 @@ - -Joanie Connection | Richie - - + +Joanie Connection | Richie + +
    Version: 2.24.0

    Joanie Connection

    Joanie delivers an API able to manage course @@ -90,6 +90,6 @@

    Lifet its lifetime is 5 minutes by default.

    Technical support

    If you encounter an issue with this documentation, please -open an issue on our repository.

    +open an issue on our repository.

    \ No newline at end of file diff --git a/docs/2.24.0/lms-backends/index.html b/docs/2.24.0/lms-backends/index.html index d31534d7f3..3c04ae0688 100644 --- a/docs/2.24.0/lms-backends/index.html +++ b/docs/2.24.0/lms-backends/index.html @@ -2,10 +2,10 @@ - -Configuring LMS Backends | Richie - - + +Configuring LMS Backends | Richie + +
    Version: 2.24.0

    Configuring LMS Backends

    Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless @@ -115,6 +115,6 @@

    Technical

    If you encounter an issue with this documentation or the backends included in Richie, please open an issue on our repository.

    If you need a custom backend, you can submit a PR or -open an issue and we will consider adding it.

    +open an issue and we will consider adding it.

    \ No newline at end of file diff --git a/docs/2.24.0/lms-connection/index.html b/docs/2.24.0/lms-connection/index.html index 4ce5957d39..2eddeb3c9c 100644 --- a/docs/2.24.0/lms-connection/index.html +++ b/docs/2.24.0/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with one or more LMS | Richie - - + +Connecting Richie with one or more LMS | Richie + + -
    Version: 2.24.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    +
    Version: 2.24.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    Richie can be connected to an LMS in several ways, ranging from SSO to a fully integrated seamless experience.

    As of today, each approach has been implemented for OpenEdX but the same could be done for @@ -63,6 +63,6 @@

    Development

    If you want to activate seamless enrollment locally for development, you will need to set up TLS domains for both Richie and OpenEdX. To do this, head over to our -guide on setting-up TLS connections for Richie and OpenEdX.

    +guide on setting-up TLS connections for Richie and OpenEdX.

    \ No newline at end of file diff --git a/docs/2.24.0/native-installation/index.html b/docs/2.24.0/native-installation/index.html index ab221e046b..cbd5fe194b 100644 --- a/docs/2.24.0/native-installation/index.html +++ b/docs/2.24.0/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.24.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.24.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native installation instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.24.0/synchronizing-course-runs/index.html b/docs/2.24.0/synchronizing-course-runs/index.html index 92639dffd0..7ea391581f 100644 --- a/docs/2.24.0/synchronizing-course-runs/index.html +++ b/docs/2.24.0/synchronizing-course-runs/index.html @@ -2,10 +2,10 @@ - -Synchronizing course runs between Richie and OpenEdX | Richie - - + +Synchronizing course runs between Richie and OpenEdX | Richie + +
    Version: 2.24.0

    Synchronizing course runs between Richie and OpenEdX

    Richie can receive automatic course runs updates on a dedicated API endpoint.

    @@ -51,6 +51,6 @@

    import hashlib
    import hmac
    import json

    from django.conf import settings

    from microsite_configuration import microsite
    import requests
    from xmodule.modulestore.django import modulestore


    def update_course(course_key, *args, **kwargs):
    """Synchronize an OpenEdX course, identified by its course key, with a Richie instance."""
    course = modulestore().get_course(course_key)
    edxapp_domain = microsite.get_value("site_domain", settings.LMS_BASE)

    data = {
    "resource_link": "https://{:s}/courses/{!s}/info".format(
    edxapp_domain, course_key
    ),
    "start": course.start and course.start.isoformat(),
    "end": course.end and course.end.isoformat(),
    "enrollment_start": course.enrollment_start and course.enrollment_start.isoformat(),
    "enrollment_end": course.enrollment_end and course.enrollment_end.isoformat(),
    "languages": [course.language or settings.LANGUAGE_CODE],
    }

    signature = hmac.new(
    setting.COURSE_HOOK["secret"].encode("utf-8"),
    msg=json.dumps(data).encode("utf-8"),
    digestmod=hashlib.sha256,
    ).hexdigest()

    response = requests.post(
    setting.COURSE_HOOK["url"],
    json=data,
    headers={"Authorization": "SIG-HMAC-SHA256 {:s}".format(signature)},
    )

    Thanks to the signal emitted in OpenEdX, this function can then be triggered each time a course is modified and published:

    -
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    +
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    \ No newline at end of file diff --git a/docs/2.24.0/tls-connection/index.html b/docs/2.24.0/tls-connection/index.html index 341b2d39ba..fc9066131e 100644 --- a/docs/2.24.0/tls-connection/index.html +++ b/docs/2.24.0/tls-connection/index.html @@ -2,10 +2,10 @@ - -Connecting Richie and OpenEdX over TLS for development | Richie - - + +Connecting Richie and OpenEdX over TLS for development | Richie + +
    Version: 2.24.0

    Connecting Richie and OpenEdX over TLS for development

    Purpose

    @@ -68,6 +68,6 @@

    $ make run-ssl

    Of course, you can still run apps without ssl by using:

    -
    $ make run
    +
    $ make run
    \ No newline at end of file diff --git a/docs/2.24.0/web-analytics/index.html b/docs/2.24.0/web-analytics/index.html index 27cf81d272..4933936303 100644 --- a/docs/2.24.0/web-analytics/index.html +++ b/docs/2.24.0/web-analytics/index.html @@ -2,13 +2,13 @@ - -Add web analytics to your site | Richie - - + +Add web analytics to your site | Richie + + -
    Version: 2.24.0

    Add web analytics to your site

    Richie has native support to Google Universal Analytics and Google Tag Manager Web Analytics solutions. +

    Version: 2.24.0

    Add web analytics to your site

    Richie has native support to Google Universal Analytics and Google Tag Manager Web Analytics solutions. The purpose of this file is to explain how you can enable one of the supported Web Analytics providers and how you can extend Richie with an alternative solution.

    Google Universal Analytics

    @@ -78,6 +78,6 @@

    +of src/frontend/js/utils/api/web-analytics/google_universal_analytics.ts and change the src/frontend/js/utils/api/web-analytics/index.ts file to include that newer provider.

    \ No newline at end of file diff --git a/docs/2.24.1/accessibility-testing/index.html b/docs/2.24.1/accessibility-testing/index.html index cdafd6c19e..d5427eeaa9 100644 --- a/docs/2.24.1/accessibility-testing/index.html +++ b/docs/2.24.1/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.24.1

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.24.1

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems on any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.24.1/api/course-run-synchronization-api/index.html b/docs/2.24.1/api/course-run-synchronization-api/index.html index 8aa6412269..258060bada 100644 --- a/docs/2.24.1/api/course-run-synchronization-api/index.html +++ b/docs/2.24.1/api/course-run-synchronization-api/index.html @@ -2,10 +2,10 @@ - -Course run synchronization API | Richie - - + +Course run synchronization API | Richie + +
    Version: 2.24.1

    Course run synchronization API

    API endpoint allowing remote systems to synchronize their course runs with a Richie instance.

    @@ -52,6 +52,6 @@

    +
    \ No newline at end of file diff --git a/docs/2.24.1/building-the-frontend/index.html b/docs/2.24.1/building-the-frontend/index.html index b3da9fe603..056d7f34ef 100644 --- a/docs/2.24.1/building-the-frontend/index.html +++ b/docs/2.24.1/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.24.1

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.24.1

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.24.1/contributing-guide/index.html b/docs/2.24.1/contributing-guide/index.html index 77e7300953..8d707992de 100644 --- a/docs/2.24.1/contributing-guide/index.html +++ b/docs/2.24.1/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.24.1

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.24.1

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.24.1/cookiecutter/index.html b/docs/2.24.1/cookiecutter/index.html index fbb46cd31a..51721712cd 100644 --- a/docs/2.24.1/cookiecutter/index.html +++ b/docs/2.24.1/cookiecutter/index.html @@ -2,13 +2,13 @@ - -Start your own site | Richie - - + +Start your own site | Richie + + -
    Version: 2.24.1

    Start your own site

    We use Cookiecutter to help you +

    Version: 2.24.1

    Start your own site

    We use Cookiecutter to help you set up a production-ready learning portal website based on Richie in seconds.

    Run Cookiecutter

    @@ -73,6 +73,6 @@

    cookiecutter --overwrite-if-exists gh:openfun/richie --directory=cookiecutter

    Help us improve this project

    After starting your project, please submit an issue let us know how it went and -what other features we should add to make it better.

    +what other features we should add to make it better.

    \ No newline at end of file diff --git a/docs/2.24.1/css-guidelines/index.html b/docs/2.24.1/css-guidelines/index.html index 2649a6a8e2..9af652da8e 100644 --- a/docs/2.24.1/css-guidelines/index.html +++ b/docs/2.24.1/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.24.1

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.24.1

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.24.1/discover/index.html b/docs/2.24.1/discover/index.html index a9a733d083..ce4bc374bd 100644 --- a/docs/2.24.1/discover/index.html +++ b/docs/2.24.1/discover/index.html @@ -2,13 +2,13 @@ - -Discover Richie | Richie - - + +Discover Richie | Richie + + -
    Version: 2.24.1

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online +

    Version: 2.24.1

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online courses and MOOCs.

    However, if you need to build a complete website with flexible content to aggregate your courses, in several languages and from different sources, you will soon need a CMS.

    @@ -51,6 +51,6 @@

    Start yo
  • override some css rules or rebuild the whole css with your own variables and customizations,
  • add any DjangoCMS plugin or feature,
  • add any Django third-party application.
  • -

    +
    \ No newline at end of file diff --git a/docs/2.24.1/displaying-connection-status/index.html b/docs/2.24.1/displaying-connection-status/index.html index 5cd55e9d41..1223f02645 100644 --- a/docs/2.24.1/displaying-connection-status/index.html +++ b/docs/2.24.1/displaying-connection-status/index.html @@ -2,10 +2,10 @@ - -Displaying OpenEdX connection status in Richie | Richie - - + +Displaying OpenEdX connection status in Richie | Richie + + +
    \ No newline at end of file diff --git a/docs/2.24.1/django-react-interop/index.html b/docs/2.24.1/django-react-interop/index.html index 1e1a031488..3f28a3f2ef 100644 --- a/docs/2.24.1/django-react-interop/index.html +++ b/docs/2.24.1/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.24.1

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.24.1

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -64,6 +64,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.24.1/docker-development/index.html b/docs/2.24.1/docker-development/index.html index cd3a62dee1..6208f01572 100644 --- a/docs/2.24.1/docker-development/index.html +++ b/docs/2.24.1/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.24.1

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.24.1

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.24.1/filters-customization/index.html b/docs/2.24.1/filters-customization/index.html index 8f4de4e61b..482eeba762 100644 --- a/docs/2.24.1/filters-customization/index.html +++ b/docs/2.24.1/filters-customization/index.html @@ -2,13 +2,13 @@ - -Customizing search filters | Richie - - + +Customizing search filters | Richie + + -
    Version: 2.24.1

    Customizing search filters

    You may want to customize the filters on the left side bar of the search page.

    +
    Version: 2.24.1

    Customizing search filters

    You may want to customize the filters on the left side bar of the search page.

    Richie makes it easy to choose which filters you want to display among the existing filters and in which order. You can also configure the existing filters to change their title or the way they behave. Lastly, you can completely override a filter or create your own custom filter @@ -88,6 +88,6 @@

    opening an issue!

    +opening an issue!

    \ No newline at end of file diff --git a/docs/2.24.1/frontend-overrides/index.html b/docs/2.24.1/frontend-overrides/index.html index 6313fe6ef9..d80236b48c 100644 --- a/docs/2.24.1/frontend-overrides/index.html +++ b/docs/2.24.1/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.24.1

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.24.1

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.24.1/installation/index.html b/docs/2.24.1/installation/index.html index bfe7901f30..7c6a196557 100644 --- a/docs/2.24.1/installation/index.html +++ b/docs/2.24.1/installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie for development | Richie - - + +Installing Richie for development | Richie + + -
    Version: 2.24.1

    Installing Richie for development

    Richie is a container-native application but can also be installed +

    +https://www.nau.edu.pt.

    \ No newline at end of file diff --git a/docs/2.24.1/internationalization/index.html b/docs/2.24.1/internationalization/index.html index 67481afa3c..f9c3b45551 100644 --- a/docs/2.24.1/internationalization/index.html +++ b/docs/2.24.1/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.24.1

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.24.1

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.24.1/joanie-connection/index.html b/docs/2.24.1/joanie-connection/index.html index 7dca550439..57b74ff038 100644 --- a/docs/2.24.1/joanie-connection/index.html +++ b/docs/2.24.1/joanie-connection/index.html @@ -2,10 +2,10 @@ - -Joanie Connection | Richie - - + +Joanie Connection | Richie + +
    Version: 2.24.1

    Joanie Connection

    Joanie delivers an API able to manage course @@ -90,6 +90,6 @@

    Lifet its lifetime is 5 minutes by default.

    Technical support

    If you encounter an issue with this documentation, please -open an issue on our repository.

    +open an issue on our repository.

    \ No newline at end of file diff --git a/docs/2.24.1/lms-backends/index.html b/docs/2.24.1/lms-backends/index.html index db0bc719bb..58826ed379 100644 --- a/docs/2.24.1/lms-backends/index.html +++ b/docs/2.24.1/lms-backends/index.html @@ -2,10 +2,10 @@ - -Configuring LMS Backends | Richie - - + +Configuring LMS Backends | Richie + +
    Version: 2.24.1

    Configuring LMS Backends

    Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless @@ -115,6 +115,6 @@

    Technical

    If you encounter an issue with this documentation or the backends included in Richie, please open an issue on our repository.

    If you need a custom backend, you can submit a PR or -open an issue and we will consider adding it.

    +open an issue and we will consider adding it.

    \ No newline at end of file diff --git a/docs/2.24.1/lms-connection/index.html b/docs/2.24.1/lms-connection/index.html index 5f64fe2147..85d7d618fd 100644 --- a/docs/2.24.1/lms-connection/index.html +++ b/docs/2.24.1/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with one or more LMS | Richie - - + +Connecting Richie with one or more LMS | Richie + + -
    Version: 2.24.1

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    +
    Version: 2.24.1

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    Richie can be connected to an LMS in several ways, ranging from SSO to a fully integrated seamless experience.

    As of today, each approach has been implemented for OpenEdX but the same could be done for @@ -63,6 +63,6 @@

    Development

    If you want to activate seamless enrollment locally for development, you will need to set up TLS domains for both Richie and OpenEdX. To do this, head over to our -guide on setting-up TLS connections for Richie and OpenEdX.

    +guide on setting-up TLS connections for Richie and OpenEdX.

    \ No newline at end of file diff --git a/docs/2.24.1/native-installation/index.html b/docs/2.24.1/native-installation/index.html index ee0bd6a182..b4c1590ff0 100644 --- a/docs/2.24.1/native-installation/index.html +++ b/docs/2.24.1/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.24.1

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.24.1

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native installation instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.24.1/synchronizing-course-runs/index.html b/docs/2.24.1/synchronizing-course-runs/index.html index 4e0f6c455e..4cd32a76cd 100644 --- a/docs/2.24.1/synchronizing-course-runs/index.html +++ b/docs/2.24.1/synchronizing-course-runs/index.html @@ -2,10 +2,10 @@ - -Synchronizing course runs between Richie and OpenEdX | Richie - - + +Synchronizing course runs between Richie and OpenEdX | Richie + +
    Version: 2.24.1

    Synchronizing course runs between Richie and OpenEdX

    Richie can receive automatic course runs updates on a dedicated API endpoint.

    @@ -51,6 +51,6 @@

    import hashlib
    import hmac
    import json

    from django.conf import settings

    from microsite_configuration import microsite
    import requests
    from xmodule.modulestore.django import modulestore


    def update_course(course_key, *args, **kwargs):
    """Synchronize an OpenEdX course, identified by its course key, with a Richie instance."""
    course = modulestore().get_course(course_key)
    edxapp_domain = microsite.get_value("site_domain", settings.LMS_BASE)

    data = {
    "resource_link": "https://{:s}/courses/{!s}/info".format(
    edxapp_domain, course_key
    ),
    "start": course.start and course.start.isoformat(),
    "end": course.end and course.end.isoformat(),
    "enrollment_start": course.enrollment_start and course.enrollment_start.isoformat(),
    "enrollment_end": course.enrollment_end and course.enrollment_end.isoformat(),
    "languages": [course.language or settings.LANGUAGE_CODE],
    }

    signature = hmac.new(
    setting.COURSE_HOOK["secret"].encode("utf-8"),
    msg=json.dumps(data).encode("utf-8"),
    digestmod=hashlib.sha256,
    ).hexdigest()

    response = requests.post(
    setting.COURSE_HOOK["url"],
    json=data,
    headers={"Authorization": "SIG-HMAC-SHA256 {:s}".format(signature)},
    )

    Thanks to the signal emitted in OpenEdX, this function can then be triggered each time a course is modified and published:

    -
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    +
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    \ No newline at end of file diff --git a/docs/2.24.1/tls-connection/index.html b/docs/2.24.1/tls-connection/index.html index 6c40c4de76..c82b787fb3 100644 --- a/docs/2.24.1/tls-connection/index.html +++ b/docs/2.24.1/tls-connection/index.html @@ -2,10 +2,10 @@ - -Connecting Richie and OpenEdX over TLS for development | Richie - - + +Connecting Richie and OpenEdX over TLS for development | Richie + +
    Version: 2.24.1

    Connecting Richie and OpenEdX over TLS for development

    Purpose

    @@ -68,6 +68,6 @@

    $ make run-ssl

    Of course, you can still run apps without ssl by using:

    -
    $ make run
    +
    $ make run
    \ No newline at end of file diff --git a/docs/2.24.1/web-analytics/index.html b/docs/2.24.1/web-analytics/index.html index f9c174ce38..e184832301 100644 --- a/docs/2.24.1/web-analytics/index.html +++ b/docs/2.24.1/web-analytics/index.html @@ -2,13 +2,13 @@ - -Add web analytics to your site | Richie - - + +Add web analytics to your site | Richie + + -
    Version: 2.24.1

    Add web analytics to your site

    Richie has native support to Google Universal Analytics and Google Tag Manager Web Analytics solutions. +

    Version: 2.24.1

    Add web analytics to your site

    Richie has native support to Google Universal Analytics and Google Tag Manager Web Analytics solutions. The purpose of this file is to explain how you can enable one of the supported Web Analytics providers and how you can extend Richie with an alternative solution.

    Google Universal Analytics

    @@ -78,6 +78,6 @@

    +of src/frontend/js/utils/api/web-analytics/google_universal_analytics.ts and change the src/frontend/js/utils/api/web-analytics/index.ts file to include that newer provider.

    \ No newline at end of file diff --git a/docs/2.25.0-beta.0/accessibility-testing/index.html b/docs/2.25.0-beta.0/accessibility-testing/index.html index d9ea506971..643490cec9 100644 --- a/docs/2.25.0-beta.0/accessibility-testing/index.html +++ b/docs/2.25.0-beta.0/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.25.0-beta.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.25.0-beta.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems on any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.25.0-beta.0/api/course-run-synchronization-api/index.html b/docs/2.25.0-beta.0/api/course-run-synchronization-api/index.html index b042c13121..a058efdec4 100644 --- a/docs/2.25.0-beta.0/api/course-run-synchronization-api/index.html +++ b/docs/2.25.0-beta.0/api/course-run-synchronization-api/index.html @@ -2,10 +2,10 @@ - -Course run synchronization API | Richie - - + +Course run synchronization API | Richie + +
    Version: 2.25.0-beta.0

    Course run synchronization API

    API endpoint allowing remote systems to synchronize their course runs with a Richie instance.

    @@ -52,6 +52,6 @@

    +
    \ No newline at end of file diff --git a/docs/2.25.0-beta.0/building-the-frontend/index.html b/docs/2.25.0-beta.0/building-the-frontend/index.html index bc70d0caf5..399798f25a 100644 --- a/docs/2.25.0-beta.0/building-the-frontend/index.html +++ b/docs/2.25.0-beta.0/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.25.0-beta.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.25.0-beta.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.25.0-beta.0/contributing-guide/index.html b/docs/2.25.0-beta.0/contributing-guide/index.html index a4d0a06c53..5741b71621 100644 --- a/docs/2.25.0-beta.0/contributing-guide/index.html +++ b/docs/2.25.0-beta.0/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.25.0-beta.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.25.0-beta.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.25.0-beta.0/cookiecutter/index.html b/docs/2.25.0-beta.0/cookiecutter/index.html index 0e59fc2c3d..bcda3aaacd 100644 --- a/docs/2.25.0-beta.0/cookiecutter/index.html +++ b/docs/2.25.0-beta.0/cookiecutter/index.html @@ -2,13 +2,13 @@ - -Start your own site | Richie - - + +Start your own site | Richie + + -
    Version: 2.25.0-beta.0

    Start your own site

    We use Cookiecutter to help you +

    Version: 2.25.0-beta.0

    Start your own site

    We use Cookiecutter to help you set up a production-ready learning portal website based on Richie in seconds.

    Run Cookiecutter

    @@ -73,6 +73,6 @@

    cookiecutter --overwrite-if-exists gh:openfun/richie --directory=cookiecutter

    Help us improve this project

    After starting your project, please submit an issue let us know how it went and -what other features we should add to make it better.

    +what other features we should add to make it better.

    \ No newline at end of file diff --git a/docs/2.25.0-beta.0/css-guidelines/index.html b/docs/2.25.0-beta.0/css-guidelines/index.html index b4d854dc38..68436a5085 100644 --- a/docs/2.25.0-beta.0/css-guidelines/index.html +++ b/docs/2.25.0-beta.0/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.25.0-beta.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.25.0-beta.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.25.0-beta.0/discover/index.html b/docs/2.25.0-beta.0/discover/index.html index 4522ce1514..b865db4937 100644 --- a/docs/2.25.0-beta.0/discover/index.html +++ b/docs/2.25.0-beta.0/discover/index.html @@ -2,13 +2,13 @@ - -Discover Richie | Richie - - + +Discover Richie | Richie + + -
    Version: 2.25.0-beta.0

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online +

    Version: 2.25.0-beta.0

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online courses and MOOCs.

    However, if you need to build a complete website with flexible content to aggregate your courses, in several languages and from different sources, you will soon need a CMS.

    @@ -51,6 +51,6 @@

    Start yo
  • override some css rules or rebuild the whole css with your own variables and customizations,
  • add any DjangoCMS plugin or feature,
  • add any Django third-party application.
  • -

    +
    \ No newline at end of file diff --git a/docs/2.25.0-beta.0/displaying-connection-status/index.html b/docs/2.25.0-beta.0/displaying-connection-status/index.html index 5c0d9978df..8bfb05ca75 100644 --- a/docs/2.25.0-beta.0/displaying-connection-status/index.html +++ b/docs/2.25.0-beta.0/displaying-connection-status/index.html @@ -2,10 +2,10 @@ - -Displaying OpenEdX connection status in Richie | Richie - - + +Displaying OpenEdX connection status in Richie | Richie + +
    +
    \ No newline at end of file diff --git a/docs/2.25.0-beta.0/django-react-interop/index.html b/docs/2.25.0-beta.0/django-react-interop/index.html index df36d85b23..9194129105 100644 --- a/docs/2.25.0-beta.0/django-react-interop/index.html +++ b/docs/2.25.0-beta.0/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.25.0-beta.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.25.0-beta.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -65,6 +65,6 @@

    Context
        {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.25.0-beta.0/docker-development/index.html b/docs/2.25.0-beta.0/docker-development/index.html index 7542489c4d..7fbbd97a6b 100644 --- a/docs/2.25.0-beta.0/docker-development/index.html +++ b/docs/2.25.0-beta.0/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.25.0-beta.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.25.0-beta.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.25.0-beta.0/filters-customization/index.html b/docs/2.25.0-beta.0/filters-customization/index.html index 6957fa9cbc..5d79301c1d 100644 --- a/docs/2.25.0-beta.0/filters-customization/index.html +++ b/docs/2.25.0-beta.0/filters-customization/index.html @@ -2,13 +2,13 @@ - -Customizing search filters | Richie - - + +Customizing search filters | Richie + + -
    Version: 2.25.0-beta.0

    Customizing search filters

    You may want to customize the filters on the left side bar of the search page.

    +
    Version: 2.25.0-beta.0

    Customizing search filters

    You may want to customize the filters on the left side bar of the search page.

    Richie makes it easy to choose which filters you want to display among the existing filters and in which order. You can also configure the existing filters to change their title or the way they behave. Lastly, you can completely override a filter or create your own custom filter @@ -88,6 +88,6 @@

    opening an issue!

    +opening an issue!

    \ No newline at end of file diff --git a/docs/2.25.0-beta.0/frontend-overrides/index.html b/docs/2.25.0-beta.0/frontend-overrides/index.html index d3570a54eb..c302edf07a 100644 --- a/docs/2.25.0-beta.0/frontend-overrides/index.html +++ b/docs/2.25.0-beta.0/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.25.0-beta.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.25.0-beta.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.25.0-beta.0/installation/index.html b/docs/2.25.0-beta.0/installation/index.html index 7cd582956c..061e390190 100644 --- a/docs/2.25.0-beta.0/installation/index.html +++ b/docs/2.25.0-beta.0/installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie for development | Richie - - + +Installing Richie for development | Richie + + -
    Version: 2.25.0-beta.0

    Installing Richie for development

    Richie is a container-native application but can also be installed +

    +https://www.nau.edu.pt.

    \ No newline at end of file diff --git a/docs/2.25.0-beta.0/internationalization/index.html b/docs/2.25.0-beta.0/internationalization/index.html index aad9458a15..7434d86434 100644 --- a/docs/2.25.0-beta.0/internationalization/index.html +++ b/docs/2.25.0-beta.0/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.25.0-beta.0

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.25.0-beta.0

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.25.0-beta.0/joanie-connection/index.html b/docs/2.25.0-beta.0/joanie-connection/index.html index 20ecbc99bf..af30db7f44 100644 --- a/docs/2.25.0-beta.0/joanie-connection/index.html +++ b/docs/2.25.0-beta.0/joanie-connection/index.html @@ -2,10 +2,10 @@ - -Joanie Connection | Richie - - + +Joanie Connection | Richie + +
    Version: 2.25.0-beta.0

    Joanie Connection

    Joanie delivers an API able to manage course @@ -92,6 +92,6 @@

    Lifet its lifetime is 5 minutes by default.

    Technical support

    If you encounter an issue with this documentation, please -open an issue on our repository.

    +open an issue on our repository.

    \ No newline at end of file diff --git a/docs/2.25.0-beta.0/lms-backends/index.html b/docs/2.25.0-beta.0/lms-backends/index.html index 38e4f4b05f..2d0b0100c6 100644 --- a/docs/2.25.0-beta.0/lms-backends/index.html +++ b/docs/2.25.0-beta.0/lms-backends/index.html @@ -2,10 +2,10 @@ - -Configuring LMS Backends | Richie - - + +Configuring LMS Backends | Richie + +
    Version: 2.25.0-beta.0

    Configuring LMS Backends

    Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless @@ -115,6 +115,6 @@

    Technical

    If you encounter an issue with this documentation or the backends included in Richie, please open an issue on our repository.

    If you need a custom backend, you can submit a PR or -open an issue and we will consider adding it.

    +open an issue and we will consider adding it.

    \ No newline at end of file diff --git a/docs/2.25.0-beta.0/lms-connection/index.html b/docs/2.25.0-beta.0/lms-connection/index.html index 7cee38afba..b4afc555a5 100644 --- a/docs/2.25.0-beta.0/lms-connection/index.html +++ b/docs/2.25.0-beta.0/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with one or more LMS | Richie - - + +Connecting Richie with one or more LMS | Richie + + -
    Version: 2.25.0-beta.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    +
    Version: 2.25.0-beta.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    Richie can be connected to an LMS in several ways, ranging from SSO to a fully integrated seamless experience.

    As of today, each approach has been implemented for OpenEdX but the same could be done for @@ -63,6 +63,6 @@

    Development

    If you want to activate seamless enrollment locally for development, you will need to set up TLS domains for both Richie and OpenEdX. To do this, head over to our -guide on setting-up TLS connections for Richie and OpenEdX.

    +guide on setting-up TLS connections for Richie and OpenEdX.

    \ No newline at end of file diff --git a/docs/2.25.0-beta.0/native-installation/index.html b/docs/2.25.0-beta.0/native-installation/index.html index 378b63d265..fc7353c06a 100644 --- a/docs/2.25.0-beta.0/native-installation/index.html +++ b/docs/2.25.0-beta.0/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.25.0-beta.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.25.0-beta.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native installation instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.25.0-beta.0/synchronizing-course-runs/index.html b/docs/2.25.0-beta.0/synchronizing-course-runs/index.html index 95f6b2f42f..4389b3f63e 100644 --- a/docs/2.25.0-beta.0/synchronizing-course-runs/index.html +++ b/docs/2.25.0-beta.0/synchronizing-course-runs/index.html @@ -2,10 +2,10 @@ - -Synchronizing course runs between Richie and OpenEdX | Richie - - + +Synchronizing course runs between Richie and OpenEdX | Richie + +
    Version: 2.25.0-beta.0

    Synchronizing course runs between Richie and OpenEdX

    Richie can receive automatic course runs updates on a dedicated API endpoint.

    @@ -51,6 +51,6 @@

    import hashlib
    import hmac
    import json

    from django.conf import settings

    from microsite_configuration import microsite
    import requests
    from xmodule.modulestore.django import modulestore


    def update_course(course_key, *args, **kwargs):
    """Synchronize an OpenEdX course, identified by its course key, with a Richie instance."""
    course = modulestore().get_course(course_key)
    edxapp_domain = microsite.get_value("site_domain", settings.LMS_BASE)

    data = {
    "resource_link": "https://{:s}/courses/{!s}/info".format(
    edxapp_domain, course_key
    ),
    "start": course.start and course.start.isoformat(),
    "end": course.end and course.end.isoformat(),
    "enrollment_start": course.enrollment_start and course.enrollment_start.isoformat(),
    "enrollment_end": course.enrollment_end and course.enrollment_end.isoformat(),
    "languages": [course.language or settings.LANGUAGE_CODE],
    }

    signature = hmac.new(
    setting.COURSE_HOOK["secret"].encode("utf-8"),
    msg=json.dumps(data).encode("utf-8"),
    digestmod=hashlib.sha256,
    ).hexdigest()

    response = requests.post(
    setting.COURSE_HOOK["url"],
    json=data,
    headers={"Authorization": "SIG-HMAC-SHA256 {:s}".format(signature)},
    )

    Thanks to the signal emitted in OpenEdX, this function can then be triggered each time a course is modified and published:

    -
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    +
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    \ No newline at end of file diff --git a/docs/2.25.0-beta.0/tls-connection/index.html b/docs/2.25.0-beta.0/tls-connection/index.html index dc4942d4b5..7f818cad7b 100644 --- a/docs/2.25.0-beta.0/tls-connection/index.html +++ b/docs/2.25.0-beta.0/tls-connection/index.html @@ -2,10 +2,10 @@ - -Connecting Richie and OpenEdX over TLS for development | Richie - - + +Connecting Richie and OpenEdX over TLS for development | Richie + +
    Version: 2.25.0-beta.0

    Connecting Richie and OpenEdX over TLS for development

    Purpose

    @@ -68,6 +68,6 @@

    $ make run-ssl

    Of course, you can still run apps without ssl by using:

    -
    $ make run
    +
    $ make run
    \ No newline at end of file diff --git a/docs/2.25.0-beta.0/web-analytics/index.html b/docs/2.25.0-beta.0/web-analytics/index.html index 1296775774..1afe4cd4e5 100644 --- a/docs/2.25.0-beta.0/web-analytics/index.html +++ b/docs/2.25.0-beta.0/web-analytics/index.html @@ -2,13 +2,13 @@ - -Add web analytics to your site | Richie - - + +Add web analytics to your site | Richie + + -
    Version: 2.25.0-beta.0

    Add web analytics to your site

    Richie has native support to Google Universal Analytics and Google Tag Manager Web Analytics solutions. +

    Version: 2.25.0-beta.0

    Add web analytics to your site

    Richie has native support to Google Universal Analytics and Google Tag Manager Web Analytics solutions. The purpose of this file is to explain how you can enable one of the supported Web Analytics providers and how you can extend Richie with an alternative solution.

    Google Universal Analytics

    @@ -78,6 +78,6 @@

    +of src/frontend/js/utils/api/web-analytics/google_universal_analytics.ts and change the src/frontend/js/utils/api/web-analytics/index.ts file to include that newer provider.

    \ No newline at end of file diff --git a/docs/2.25.0-beta.1/accessibility-testing/index.html b/docs/2.25.0-beta.1/accessibility-testing/index.html index 4d8ee64041..f8ae555772 100644 --- a/docs/2.25.0-beta.1/accessibility-testing/index.html +++ b/docs/2.25.0-beta.1/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.25.0-beta.1

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.25.0-beta.1

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems on any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.25.0-beta.1/api/course-run-synchronization-api/index.html b/docs/2.25.0-beta.1/api/course-run-synchronization-api/index.html index 4b6998a2c4..13055e0a05 100644 --- a/docs/2.25.0-beta.1/api/course-run-synchronization-api/index.html +++ b/docs/2.25.0-beta.1/api/course-run-synchronization-api/index.html @@ -2,10 +2,10 @@ - -Course run synchronization API | Richie - - + +Course run synchronization API | Richie + +
    Version: 2.25.0-beta.1

    Course run synchronization API

    API endpoint allowing remote systems to synchronize their course runs with a Richie instance.

    @@ -52,6 +52,6 @@

    +
    \ No newline at end of file diff --git a/docs/2.25.0-beta.1/building-the-frontend/index.html b/docs/2.25.0-beta.1/building-the-frontend/index.html index ba8cce5a2e..eb09399885 100644 --- a/docs/2.25.0-beta.1/building-the-frontend/index.html +++ b/docs/2.25.0-beta.1/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.25.0-beta.1

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.25.0-beta.1

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.25.0-beta.1/contributing-guide/index.html b/docs/2.25.0-beta.1/contributing-guide/index.html index 7a72815861..3fe8a7f0cb 100644 --- a/docs/2.25.0-beta.1/contributing-guide/index.html +++ b/docs/2.25.0-beta.1/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.25.0-beta.1

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.25.0-beta.1

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.25.0-beta.1/cookiecutter/index.html b/docs/2.25.0-beta.1/cookiecutter/index.html index 51b1c9fddf..50d70490ba 100644 --- a/docs/2.25.0-beta.1/cookiecutter/index.html +++ b/docs/2.25.0-beta.1/cookiecutter/index.html @@ -2,13 +2,13 @@ - -Start your own site | Richie - - + +Start your own site | Richie + + -
    Version: 2.25.0-beta.1

    Start your own site

    We use Cookiecutter to help you +

    Version: 2.25.0-beta.1

    Start your own site

    We use Cookiecutter to help you set up a production-ready learning portal website based on Richie in seconds.

    Run Cookiecutter

    @@ -73,6 +73,6 @@

    cookiecutter --overwrite-if-exists gh:openfun/richie --directory=cookiecutter

    Help us improve this project

    After starting your project, please submit an issue let us know how it went and -what other features we should add to make it better.

    +what other features we should add to make it better.

    \ No newline at end of file diff --git a/docs/2.25.0-beta.1/css-guidelines/index.html b/docs/2.25.0-beta.1/css-guidelines/index.html index f8f1e64816..e2e0e91bcc 100644 --- a/docs/2.25.0-beta.1/css-guidelines/index.html +++ b/docs/2.25.0-beta.1/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.25.0-beta.1

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.25.0-beta.1

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.25.0-beta.1/discover/index.html b/docs/2.25.0-beta.1/discover/index.html index 04642201fc..b5270ef28d 100644 --- a/docs/2.25.0-beta.1/discover/index.html +++ b/docs/2.25.0-beta.1/discover/index.html @@ -2,13 +2,13 @@ - -Discover Richie | Richie - - + +Discover Richie | Richie + + -
    Version: 2.25.0-beta.1

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online +

    Version: 2.25.0-beta.1

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online courses and MOOCs.

    However, if you need to build a complete website with flexible content to aggregate your courses, in several languages and from different sources, you will soon need a CMS.

    @@ -51,6 +51,6 @@

    Start yo
  • override some css rules or rebuild the whole css with your own variables and customizations,
  • add any DjangoCMS plugin or feature,
  • add any Django third-party application.
  • -

    +
    \ No newline at end of file diff --git a/docs/2.25.0-beta.1/displaying-connection-status/index.html b/docs/2.25.0-beta.1/displaying-connection-status/index.html index 65e9c68ab3..f8188aba80 100644 --- a/docs/2.25.0-beta.1/displaying-connection-status/index.html +++ b/docs/2.25.0-beta.1/displaying-connection-status/index.html @@ -2,10 +2,10 @@ - -Displaying OpenEdX connection status in Richie | Richie - - + +Displaying OpenEdX connection status in Richie | Richie + +
    +
    \ No newline at end of file diff --git a/docs/2.25.0-beta.1/django-react-interop/index.html b/docs/2.25.0-beta.1/django-react-interop/index.html index 39396a3e74..c36f2b5791 100644 --- a/docs/2.25.0-beta.1/django-react-interop/index.html +++ b/docs/2.25.0-beta.1/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.25.0-beta.1

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.25.0-beta.1

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -65,6 +65,6 @@

    Context
        {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.25.0-beta.1/docker-development/index.html b/docs/2.25.0-beta.1/docker-development/index.html index 5b40b257ab..cc56159aab 100644 --- a/docs/2.25.0-beta.1/docker-development/index.html +++ b/docs/2.25.0-beta.1/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.25.0-beta.1

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.25.0-beta.1

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.25.0-beta.1/filters-customization/index.html b/docs/2.25.0-beta.1/filters-customization/index.html index 8c66ba1fb8..ac2f6758a6 100644 --- a/docs/2.25.0-beta.1/filters-customization/index.html +++ b/docs/2.25.0-beta.1/filters-customization/index.html @@ -2,13 +2,13 @@ - -Customizing search filters | Richie - - + +Customizing search filters | Richie + + -
    Version: 2.25.0-beta.1

    Customizing search filters

    You may want to customize the filters on the left side bar of the search page.

    +
    Version: 2.25.0-beta.1

    Customizing search filters

    You may want to customize the filters on the left side bar of the search page.

    Richie makes it easy to choose which filters you want to display among the existing filters and in which order. You can also configure the existing filters to change their title or the way they behave. Lastly, you can completely override a filter or create your own custom filter @@ -88,6 +88,6 @@

    opening an issue!

    +opening an issue!

    \ No newline at end of file diff --git a/docs/2.25.0-beta.1/frontend-overrides/index.html b/docs/2.25.0-beta.1/frontend-overrides/index.html index 5a5f039e81..5bea1a02d0 100644 --- a/docs/2.25.0-beta.1/frontend-overrides/index.html +++ b/docs/2.25.0-beta.1/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.25.0-beta.1

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.25.0-beta.1

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.25.0-beta.1/installation/index.html b/docs/2.25.0-beta.1/installation/index.html index b700439811..995400e64c 100644 --- a/docs/2.25.0-beta.1/installation/index.html +++ b/docs/2.25.0-beta.1/installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie for development | Richie - - + +Installing Richie for development | Richie + + -
    Version: 2.25.0-beta.1

    Installing Richie for development

    Richie is a container-native application but can also be installed +

    +https://www.nau.edu.pt.

    \ No newline at end of file diff --git a/docs/2.25.0-beta.1/internationalization/index.html b/docs/2.25.0-beta.1/internationalization/index.html index 6dcf6c1434..9aa66f1c75 100644 --- a/docs/2.25.0-beta.1/internationalization/index.html +++ b/docs/2.25.0-beta.1/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.25.0-beta.1

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.25.0-beta.1

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.25.0-beta.1/joanie-connection/index.html b/docs/2.25.0-beta.1/joanie-connection/index.html index f497284926..2fc7ebd155 100644 --- a/docs/2.25.0-beta.1/joanie-connection/index.html +++ b/docs/2.25.0-beta.1/joanie-connection/index.html @@ -2,10 +2,10 @@ - -Joanie Connection | Richie - - + +Joanie Connection | Richie + +
    Version: 2.25.0-beta.1

    Joanie Connection

    Joanie delivers an API able to manage course @@ -92,6 +92,6 @@

    Lifet its lifetime is 5 minutes by default.

    Technical support

    If you encounter an issue with this documentation, please -open an issue on our repository.

    +open an issue on our repository.

    \ No newline at end of file diff --git a/docs/2.25.0-beta.1/lms-backends/index.html b/docs/2.25.0-beta.1/lms-backends/index.html index 5c54876f1d..e1d4065645 100644 --- a/docs/2.25.0-beta.1/lms-backends/index.html +++ b/docs/2.25.0-beta.1/lms-backends/index.html @@ -2,10 +2,10 @@ - -Configuring LMS Backends | Richie - - + +Configuring LMS Backends | Richie + +
    Version: 2.25.0-beta.1

    Configuring LMS Backends

    Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless @@ -115,6 +115,6 @@

    Technical

    If you encounter an issue with this documentation or the backends included in Richie, please open an issue on our repository.

    If you need a custom backend, you can submit a PR or -open an issue and we will consider adding it.

    +open an issue and we will consider adding it.

    \ No newline at end of file diff --git a/docs/2.25.0-beta.1/lms-connection/index.html b/docs/2.25.0-beta.1/lms-connection/index.html index f4bd29235e..525bf9e322 100644 --- a/docs/2.25.0-beta.1/lms-connection/index.html +++ b/docs/2.25.0-beta.1/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with one or more LMS | Richie - - + +Connecting Richie with one or more LMS | Richie + + -
    Version: 2.25.0-beta.1

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    +
    Version: 2.25.0-beta.1

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    Richie can be connected to an LMS in several ways, ranging from SSO to a fully integrated seamless experience.

    As of today, each approach has been implemented for OpenEdX but the same could be done for @@ -63,6 +63,6 @@

    Development

    If you want to activate seamless enrollment locally for development, you will need to set up TLS domains for both Richie and OpenEdX. To do this, head over to our -guide on setting-up TLS connections for Richie and OpenEdX.

    +guide on setting-up TLS connections for Richie and OpenEdX.

    \ No newline at end of file diff --git a/docs/2.25.0-beta.1/native-installation/index.html b/docs/2.25.0-beta.1/native-installation/index.html index 1473b272a2..3757c84cb2 100644 --- a/docs/2.25.0-beta.1/native-installation/index.html +++ b/docs/2.25.0-beta.1/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.25.0-beta.1

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.25.0-beta.1

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native installation instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.25.0-beta.1/synchronizing-course-runs/index.html b/docs/2.25.0-beta.1/synchronizing-course-runs/index.html index ffa51fd384..4bd19847ca 100644 --- a/docs/2.25.0-beta.1/synchronizing-course-runs/index.html +++ b/docs/2.25.0-beta.1/synchronizing-course-runs/index.html @@ -2,10 +2,10 @@ - -Synchronizing course runs between Richie and OpenEdX | Richie - - + +Synchronizing course runs between Richie and OpenEdX | Richie + +
    Version: 2.25.0-beta.1

    Synchronizing course runs between Richie and OpenEdX

    Richie can receive automatic course runs updates on a dedicated API endpoint.

    @@ -51,6 +51,6 @@

    import hashlib
    import hmac
    import json

    from django.conf import settings

    from microsite_configuration import microsite
    import requests
    from xmodule.modulestore.django import modulestore


    def update_course(course_key, *args, **kwargs):
    """Synchronize an OpenEdX course, identified by its course key, with a Richie instance."""
    course = modulestore().get_course(course_key)
    edxapp_domain = microsite.get_value("site_domain", settings.LMS_BASE)

    data = {
    "resource_link": "https://{:s}/courses/{!s}/info".format(
    edxapp_domain, course_key
    ),
    "start": course.start and course.start.isoformat(),
    "end": course.end and course.end.isoformat(),
    "enrollment_start": course.enrollment_start and course.enrollment_start.isoformat(),
    "enrollment_end": course.enrollment_end and course.enrollment_end.isoformat(),
    "languages": [course.language or settings.LANGUAGE_CODE],
    }

    signature = hmac.new(
    setting.COURSE_HOOK["secret"].encode("utf-8"),
    msg=json.dumps(data).encode("utf-8"),
    digestmod=hashlib.sha256,
    ).hexdigest()

    response = requests.post(
    setting.COURSE_HOOK["url"],
    json=data,
    headers={"Authorization": "SIG-HMAC-SHA256 {:s}".format(signature)},
    )

    Thanks to the signal emitted in OpenEdX, this function can then be triggered each time a course is modified and published:

    -
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    +
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    \ No newline at end of file diff --git a/docs/2.25.0-beta.1/tls-connection/index.html b/docs/2.25.0-beta.1/tls-connection/index.html index 65adafacbd..fe3ebebfbe 100644 --- a/docs/2.25.0-beta.1/tls-connection/index.html +++ b/docs/2.25.0-beta.1/tls-connection/index.html @@ -2,10 +2,10 @@ - -Connecting Richie and OpenEdX over TLS for development | Richie - - + +Connecting Richie and OpenEdX over TLS for development | Richie + +
    Version: 2.25.0-beta.1

    Connecting Richie and OpenEdX over TLS for development

    Purpose

    @@ -68,6 +68,6 @@

    $ make run-ssl

    Of course, you can still run apps without ssl by using:

    -
    $ make run
    +
    $ make run
    \ No newline at end of file diff --git a/docs/2.25.0-beta.1/web-analytics/index.html b/docs/2.25.0-beta.1/web-analytics/index.html index c47b078c1a..828df2968a 100644 --- a/docs/2.25.0-beta.1/web-analytics/index.html +++ b/docs/2.25.0-beta.1/web-analytics/index.html @@ -2,13 +2,13 @@ - -Add web analytics to your site | Richie - - + +Add web analytics to your site | Richie + + -
    Version: 2.25.0-beta.1

    Add web analytics to your site

    Richie has native support to Google Universal Analytics and Google Tag Manager Web Analytics solutions. +

    Version: 2.25.0-beta.1

    Add web analytics to your site

    Richie has native support to Google Universal Analytics and Google Tag Manager Web Analytics solutions. The purpose of this file is to explain how you can enable one of the supported Web Analytics providers and how you can extend Richie with an alternative solution.

    Google Universal Analytics

    @@ -78,6 +78,6 @@

    +of src/frontend/js/utils/api/web-analytics/google_universal_analytics.ts and change the src/frontend/js/utils/api/web-analytics/index.ts file to include that newer provider.

    \ No newline at end of file diff --git a/docs/2.3.0/accessibility-testing/index.html b/docs/2.3.0/accessibility-testing/index.html index 40965959b5..8faa9da25f 100644 --- a/docs/2.3.0/accessibility-testing/index.html +++ b/docs/2.3.0/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.3.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.3.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems in any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.3.0/building-the-frontend/index.html b/docs/2.3.0/building-the-frontend/index.html index b272294f8f..67047bebe7 100644 --- a/docs/2.3.0/building-the-frontend/index.html +++ b/docs/2.3.0/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.3.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.3.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.3.0/contributing-guide/index.html b/docs/2.3.0/contributing-guide/index.html index 6df19bd361..4aa5eeb2fd 100644 --- a/docs/2.3.0/contributing-guide/index.html +++ b/docs/2.3.0/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.3.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.3.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.3.0/css-guidelines/index.html b/docs/2.3.0/css-guidelines/index.html index 8cfdb7327c..36cd21453a 100644 --- a/docs/2.3.0/css-guidelines/index.html +++ b/docs/2.3.0/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.3.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.3.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.3.0/discover/index.html b/docs/2.3.0/discover/index.html index 750bbcedcf..a7135abffa 100644 --- a/docs/2.3.0/discover/index.html +++ b/docs/2.3.0/discover/index.html @@ -2,13 +2,13 @@ - -Getting started with Richie | Richie - - + +Getting started with Richie | Richie + + -
    Version: 2.3.0

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    +
    Version: 2.3.0

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    Login/password are admin/admin. The database is regularly flushed.

    Architecture

    Richie is a container-native application but can also be installed @@ -60,6 +60,6 @@

    Advanced - Connecting Richie to OpenEdx

    If you want users to enroll on courses in OpenEdx directly from Richie via API calls, you should read the advanced guide to connect -Richie to OpenEdx over TLS.

    +Richie to OpenEdx over TLS.

    \ No newline at end of file diff --git a/docs/2.3.0/django-react-interop/index.html b/docs/2.3.0/django-react-interop/index.html index 7facbfd7fd..1da0a7facb 100644 --- a/docs/2.3.0/django-react-interop/index.html +++ b/docs/2.3.0/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.3.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.3.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -64,6 +64,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.3.0/docker-development/index.html b/docs/2.3.0/docker-development/index.html index 1b6a51c4e0..76613de1be 100644 --- a/docs/2.3.0/docker-development/index.html +++ b/docs/2.3.0/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.3.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.3.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.3.0/frontend-overrides/index.html b/docs/2.3.0/frontend-overrides/index.html index 6aa51ba764..a06f053c6d 100644 --- a/docs/2.3.0/frontend-overrides/index.html +++ b/docs/2.3.0/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.3.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.3.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.3.0/internationalization/index.html b/docs/2.3.0/internationalization/index.html index 621dc837c3..8f0db35766 100644 --- a/docs/2.3.0/internationalization/index.html +++ b/docs/2.3.0/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.3.0

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.3.0

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.3.0/lms-connection/index.html b/docs/2.3.0/lms-connection/index.html index 1b5b7cf969..d6a7dbf4ff 100644 --- a/docs/2.3.0/lms-connection/index.html +++ b/docs/2.3.0/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with an LMS | Richie - - + +Connecting Richie with an LMS | Richie + + -
    Version: 2.3.0

    Connecting Richie with an LMS

    richie can be connected to one or more Learning Management Systems (LMS) like OpenEdx, Moodle +

    Version: 2.3.0

    Connecting Richie with an LMS

    richie can be connected to one or more Learning Management Systems (LMS) like OpenEdx, Moodle or Canvas for a seamless experience between browsing the course catalog on richie and following the course itself on the LMS.

    In order to connect richie with a LMS, there is an API bridge @@ -81,6 +81,6 @@

    https://richie.local.dev:8070 without browser warning about the certificate validity.

    You need to follow these steps once. If you want to use SSL later, just use make run-ssl to run OpenEdx and Richie apps. -Of course, you can still run apps without ssl by using make run.

    +Of course, you can still run apps without ssl by using make run.

    \ No newline at end of file diff --git a/docs/2.3.0/native-installation/index.html b/docs/2.3.0/native-installation/index.html index 996d82a48f..6ec430ccbd 100644 --- a/docs/2.3.0/native-installation/index.html +++ b/docs/2.3.0/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.3.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.3.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.3.1/accessibility-testing/index.html b/docs/2.3.1/accessibility-testing/index.html index 326303605c..2f219dae97 100644 --- a/docs/2.3.1/accessibility-testing/index.html +++ b/docs/2.3.1/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.3.1

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.3.1

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems in any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.3.1/building-the-frontend/index.html b/docs/2.3.1/building-the-frontend/index.html index 8b45152df9..96a538ddf1 100644 --- a/docs/2.3.1/building-the-frontend/index.html +++ b/docs/2.3.1/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.3.1

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.3.1

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.3.1/contributing-guide/index.html b/docs/2.3.1/contributing-guide/index.html index 2a987f3e29..97b75eb055 100644 --- a/docs/2.3.1/contributing-guide/index.html +++ b/docs/2.3.1/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.3.1

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.3.1

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.3.1/css-guidelines/index.html b/docs/2.3.1/css-guidelines/index.html index 4c1e9cc7ea..919152fad2 100644 --- a/docs/2.3.1/css-guidelines/index.html +++ b/docs/2.3.1/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.3.1

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.3.1

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.3.1/discover/index.html b/docs/2.3.1/discover/index.html index 36621a3771..14b99cc422 100644 --- a/docs/2.3.1/discover/index.html +++ b/docs/2.3.1/discover/index.html @@ -2,13 +2,13 @@ - -Getting started with Richie | Richie - - + +Getting started with Richie | Richie + + -
    Version: 2.3.1

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    +
    Version: 2.3.1

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    Login/password are admin/admin. The database is regularly flushed.

    Architecture

    Richie is a container-native application but can also be installed @@ -60,6 +60,6 @@

    Advanced - Connecting Richie to OpenEdx

    If you want users to enroll on courses in OpenEdx directly from Richie via API calls, you should read the advanced guide to connect -Richie to OpenEdx over TLS.

    +Richie to OpenEdx over TLS.

    \ No newline at end of file diff --git a/docs/2.3.1/django-react-interop/index.html b/docs/2.3.1/django-react-interop/index.html index 8b64d56cba..8ecd74c154 100644 --- a/docs/2.3.1/django-react-interop/index.html +++ b/docs/2.3.1/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.3.1

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.3.1

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -64,6 +64,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.3.1/docker-development/index.html b/docs/2.3.1/docker-development/index.html index a82e3d85db..b41e0250aa 100644 --- a/docs/2.3.1/docker-development/index.html +++ b/docs/2.3.1/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.3.1

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.3.1

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.3.1/frontend-overrides/index.html b/docs/2.3.1/frontend-overrides/index.html index 36f295a8f4..a6b71e8e63 100644 --- a/docs/2.3.1/frontend-overrides/index.html +++ b/docs/2.3.1/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.3.1

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.3.1

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.3.1/internationalization/index.html b/docs/2.3.1/internationalization/index.html index d0dda4588f..303e6015b6 100644 --- a/docs/2.3.1/internationalization/index.html +++ b/docs/2.3.1/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.3.1

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.3.1

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.3.1/lms-connection/index.html b/docs/2.3.1/lms-connection/index.html index a0a41e6e42..9c775bb5fe 100644 --- a/docs/2.3.1/lms-connection/index.html +++ b/docs/2.3.1/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with an LMS | Richie - - + +Connecting Richie with an LMS | Richie + + -
    Version: 2.3.1

    Connecting Richie with an LMS

    richie can be connected to one or more Learning Management Systems (LMS) like OpenEdx, Moodle +

    Version: 2.3.1

    Connecting Richie with an LMS

    richie can be connected to one or more Learning Management Systems (LMS) like OpenEdx, Moodle or Canvas for a seamless experience between browsing the course catalog on richie and following the course itself on the LMS.

    In order to connect richie with a LMS, there is an API bridge @@ -81,6 +81,6 @@

    https://richie.local.dev:8070 without browser warning about the certificate validity.

    You need to follow these steps once. If you want to use SSL later, just use make run-ssl to run OpenEdx and Richie apps. -Of course, you can still run apps without ssl by using make run.

    +Of course, you can still run apps without ssl by using make run.

    \ No newline at end of file diff --git a/docs/2.3.1/native-installation/index.html b/docs/2.3.1/native-installation/index.html index 46d8cb880a..69fcce623d 100644 --- a/docs/2.3.1/native-installation/index.html +++ b/docs/2.3.1/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.3.1

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.3.1

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.3.2/accessibility-testing/index.html b/docs/2.3.2/accessibility-testing/index.html index a1478bfa04..9eda8d34ec 100644 --- a/docs/2.3.2/accessibility-testing/index.html +++ b/docs/2.3.2/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.3.2

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.3.2

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems in any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.3.2/building-the-frontend/index.html b/docs/2.3.2/building-the-frontend/index.html index bbed6a7ed6..53330a2d9a 100644 --- a/docs/2.3.2/building-the-frontend/index.html +++ b/docs/2.3.2/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.3.2

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.3.2

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.3.2/contributing-guide/index.html b/docs/2.3.2/contributing-guide/index.html index 2c5c7d7c37..f1164a8b3c 100644 --- a/docs/2.3.2/contributing-guide/index.html +++ b/docs/2.3.2/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.3.2

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.3.2

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.3.2/css-guidelines/index.html b/docs/2.3.2/css-guidelines/index.html index 069f00f80b..f122292339 100644 --- a/docs/2.3.2/css-guidelines/index.html +++ b/docs/2.3.2/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.3.2

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.3.2

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.3.2/discover/index.html b/docs/2.3.2/discover/index.html index af994fb8df..2976cf0cf0 100644 --- a/docs/2.3.2/discover/index.html +++ b/docs/2.3.2/discover/index.html @@ -2,13 +2,13 @@ - -Getting started with Richie | Richie - - + +Getting started with Richie | Richie + + -
    Version: 2.3.2

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    +
    Version: 2.3.2

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    Login/password are admin/admin. The database is regularly flushed.

    Architecture

    Richie is a container-native application but can also be installed @@ -60,6 +60,6 @@

    Advanced - Connecting Richie to OpenEdx

    If you want users to enroll on courses in OpenEdx directly from Richie via API calls, you should read the advanced guide to connect -Richie to OpenEdx over TLS.

    +Richie to OpenEdx over TLS.

    \ No newline at end of file diff --git a/docs/2.3.2/django-react-interop/index.html b/docs/2.3.2/django-react-interop/index.html index b51201fd92..9e505db0b9 100644 --- a/docs/2.3.2/django-react-interop/index.html +++ b/docs/2.3.2/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.3.2

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.3.2

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -64,6 +64,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.3.2/docker-development/index.html b/docs/2.3.2/docker-development/index.html index c95b04668b..1a9b881f49 100644 --- a/docs/2.3.2/docker-development/index.html +++ b/docs/2.3.2/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.3.2

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.3.2

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.3.2/frontend-overrides/index.html b/docs/2.3.2/frontend-overrides/index.html index d8e96d8c6c..e6db49116a 100644 --- a/docs/2.3.2/frontend-overrides/index.html +++ b/docs/2.3.2/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.3.2

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.3.2

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.3.2/internationalization/index.html b/docs/2.3.2/internationalization/index.html index 84b8a1336d..b0765dabfa 100644 --- a/docs/2.3.2/internationalization/index.html +++ b/docs/2.3.2/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.3.2

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.3.2

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.3.2/lms-connection/index.html b/docs/2.3.2/lms-connection/index.html index dd39494818..9afb1f5241 100644 --- a/docs/2.3.2/lms-connection/index.html +++ b/docs/2.3.2/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with an LMS | Richie - - + +Connecting Richie with an LMS | Richie + + -
    Version: 2.3.2

    Connecting Richie with an LMS

    richie can be connected to one or more Learning Management Systems (LMS) like OpenEdx, Moodle +

    Version: 2.3.2

    Connecting Richie with an LMS

    richie can be connected to one or more Learning Management Systems (LMS) like OpenEdx, Moodle or Canvas for a seamless experience between browsing the course catalog on richie and following the course itself on the LMS.

    In order to connect richie with a LMS, there is an API bridge @@ -81,6 +81,6 @@

    https://richie.local.dev:8070 without browser warning about the certificate validity.

    You need to follow these steps once. If you want to use SSL later, just use make run-ssl to run OpenEdx and Richie apps. -Of course, you can still run apps without ssl by using make run.

    +Of course, you can still run apps without ssl by using make run.

    \ No newline at end of file diff --git a/docs/2.3.2/native-installation/index.html b/docs/2.3.2/native-installation/index.html index bd4c62ed28..d1a220a991 100644 --- a/docs/2.3.2/native-installation/index.html +++ b/docs/2.3.2/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.3.2

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.3.2

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.3.3/accessibility-testing/index.html b/docs/2.3.3/accessibility-testing/index.html index 2e03dde3ab..00cfc771a0 100644 --- a/docs/2.3.3/accessibility-testing/index.html +++ b/docs/2.3.3/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.3.3

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.3.3

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems in any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.3.3/building-the-frontend/index.html b/docs/2.3.3/building-the-frontend/index.html index 70633568b7..f40121fba7 100644 --- a/docs/2.3.3/building-the-frontend/index.html +++ b/docs/2.3.3/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.3.3

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.3.3

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.3.3/contributing-guide/index.html b/docs/2.3.3/contributing-guide/index.html index 92a4cbb2ee..f5a204fd14 100644 --- a/docs/2.3.3/contributing-guide/index.html +++ b/docs/2.3.3/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.3.3

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.3.3

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.3.3/css-guidelines/index.html b/docs/2.3.3/css-guidelines/index.html index 12616f2d55..fea5dbd15b 100644 --- a/docs/2.3.3/css-guidelines/index.html +++ b/docs/2.3.3/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.3.3

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.3.3

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.3.3/discover/index.html b/docs/2.3.3/discover/index.html index f3f70c83df..a8ce838ea7 100644 --- a/docs/2.3.3/discover/index.html +++ b/docs/2.3.3/discover/index.html @@ -2,13 +2,13 @@ - -Getting started with Richie | Richie - - + +Getting started with Richie | Richie + + -
    Version: 2.3.3

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    +
    Version: 2.3.3

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    Login/password are admin/admin. The database is regularly flushed.

    Architecture

    Richie is a container-native application but can also be installed @@ -60,6 +60,6 @@

    Advanced - Connecting Richie to OpenEdx

    If you want users to enroll on courses in OpenEdx directly from Richie via API calls, you should read the advanced guide to connect -Richie to OpenEdx over TLS.

    +Richie to OpenEdx over TLS.

    \ No newline at end of file diff --git a/docs/2.3.3/django-react-interop/index.html b/docs/2.3.3/django-react-interop/index.html index 527aa2dd23..af311d516c 100644 --- a/docs/2.3.3/django-react-interop/index.html +++ b/docs/2.3.3/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.3.3

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.3.3

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -64,6 +64,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.3.3/docker-development/index.html b/docs/2.3.3/docker-development/index.html index b0bb15d51f..49be19c20e 100644 --- a/docs/2.3.3/docker-development/index.html +++ b/docs/2.3.3/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.3.3

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.3.3

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.3.3/frontend-overrides/index.html b/docs/2.3.3/frontend-overrides/index.html index 3e9cf4b42b..19e5ffb473 100644 --- a/docs/2.3.3/frontend-overrides/index.html +++ b/docs/2.3.3/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.3.3

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.3.3

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.3.3/internationalization/index.html b/docs/2.3.3/internationalization/index.html index 39e147c043..30b04586d3 100644 --- a/docs/2.3.3/internationalization/index.html +++ b/docs/2.3.3/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.3.3

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.3.3

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.3.3/lms-connection/index.html b/docs/2.3.3/lms-connection/index.html index 05d67ce080..8928786500 100644 --- a/docs/2.3.3/lms-connection/index.html +++ b/docs/2.3.3/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with an LMS | Richie - - + +Connecting Richie with an LMS | Richie + + -
    Version: 2.3.3

    Connecting Richie with an LMS

    richie can be connected to one or more Learning Management Systems (LMS) like OpenEdx, Moodle +

    Version: 2.3.3

    Connecting Richie with an LMS

    richie can be connected to one or more Learning Management Systems (LMS) like OpenEdx, Moodle or Canvas for a seamless experience between browsing the course catalog on richie and following the course itself on the LMS.

    In order to connect richie with a LMS, there is an API bridge @@ -81,6 +81,6 @@

    https://richie.local.dev:8070 without browser warning about the certificate validity.

    You need to follow these steps once. If you want to use SSL later, just use make run-ssl to run OpenEdx and Richie apps. -Of course, you can still run apps without ssl by using make run.

    +Of course, you can still run apps without ssl by using make run.

    \ No newline at end of file diff --git a/docs/2.3.3/native-installation/index.html b/docs/2.3.3/native-installation/index.html index 637a6d5b49..f640cb2e45 100644 --- a/docs/2.3.3/native-installation/index.html +++ b/docs/2.3.3/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.3.3

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.3.3

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.4.0/accessibility-testing/index.html b/docs/2.4.0/accessibility-testing/index.html index 0086b4af0f..05713ccb52 100644 --- a/docs/2.4.0/accessibility-testing/index.html +++ b/docs/2.4.0/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.4.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.4.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems in any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.4.0/building-the-frontend/index.html b/docs/2.4.0/building-the-frontend/index.html index 76f249f0a0..7e35231ce6 100644 --- a/docs/2.4.0/building-the-frontend/index.html +++ b/docs/2.4.0/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.4.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.4.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.4.0/contributing-guide/index.html b/docs/2.4.0/contributing-guide/index.html index 591060378d..571ef26d06 100644 --- a/docs/2.4.0/contributing-guide/index.html +++ b/docs/2.4.0/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.4.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.4.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.4.0/css-guidelines/index.html b/docs/2.4.0/css-guidelines/index.html index 7fde27afb2..3e7ee0f1c1 100644 --- a/docs/2.4.0/css-guidelines/index.html +++ b/docs/2.4.0/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.4.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.4.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.4.0/discover/index.html b/docs/2.4.0/discover/index.html index f49f6be0e7..f808c0256f 100644 --- a/docs/2.4.0/discover/index.html +++ b/docs/2.4.0/discover/index.html @@ -2,13 +2,13 @@ - -Getting started with Richie | Richie - - + +Getting started with Richie | Richie + + -
    Version: 2.4.0

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    +
    Version: 2.4.0

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    Login/password are admin/admin. The database is regularly flushed.

    Architecture

    Richie is a container-native application but can also be installed @@ -60,6 +60,6 @@

    Advanced - Connecting Richie to OpenEdx

    If you want users to enroll on courses in OpenEdx directly from Richie via API calls, you should read the advanced guide to connect -Richie to OpenEdx over TLS.

    +Richie to OpenEdx over TLS.

    \ No newline at end of file diff --git a/docs/2.4.0/django-react-interop/index.html b/docs/2.4.0/django-react-interop/index.html index f49e6518cf..0e8050da41 100644 --- a/docs/2.4.0/django-react-interop/index.html +++ b/docs/2.4.0/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.4.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.4.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -64,6 +64,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.4.0/docker-development/index.html b/docs/2.4.0/docker-development/index.html index aaa9684984..9c688e3056 100644 --- a/docs/2.4.0/docker-development/index.html +++ b/docs/2.4.0/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.4.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.4.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.4.0/frontend-overrides/index.html b/docs/2.4.0/frontend-overrides/index.html index 033e0b5d3c..3a489d531f 100644 --- a/docs/2.4.0/frontend-overrides/index.html +++ b/docs/2.4.0/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.4.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.4.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.4.0/internationalization/index.html b/docs/2.4.0/internationalization/index.html index 65e83bf716..9de54a2f76 100644 --- a/docs/2.4.0/internationalization/index.html +++ b/docs/2.4.0/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.4.0

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.4.0

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.4.0/lms-connection/index.html b/docs/2.4.0/lms-connection/index.html index 70deeecc03..a0f1f346e1 100644 --- a/docs/2.4.0/lms-connection/index.html +++ b/docs/2.4.0/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with an LMS | Richie - - + +Connecting Richie with an LMS | Richie + + -
    Version: 2.4.0

    Connecting Richie with an LMS

    richie can be connected to one or more Learning Management Systems (LMS) like OpenEdx, Moodle +

    Version: 2.4.0

    Connecting Richie with an LMS

    richie can be connected to one or more Learning Management Systems (LMS) like OpenEdx, Moodle or Canvas for a seamless experience between browsing the course catalog on richie and following the course itself on the LMS.

    In order to connect richie with a LMS, there is an API bridge @@ -81,6 +81,6 @@

    https://richie.local.dev:8070 without browser warning about the certificate validity.

    You need to follow these steps once. If you want to use SSL later, just use make run-ssl to run OpenEdx and Richie apps. -Of course, you can still run apps without ssl by using make run.

    +Of course, you can still run apps without ssl by using make run.

    \ No newline at end of file diff --git a/docs/2.4.0/native-installation/index.html b/docs/2.4.0/native-installation/index.html index 813c02a490..52a5785ccc 100644 --- a/docs/2.4.0/native-installation/index.html +++ b/docs/2.4.0/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.4.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.4.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.5.0/accessibility-testing/index.html b/docs/2.5.0/accessibility-testing/index.html index 9a030a5224..069d2591df 100644 --- a/docs/2.5.0/accessibility-testing/index.html +++ b/docs/2.5.0/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.5.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.5.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems in any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.5.0/building-the-frontend/index.html b/docs/2.5.0/building-the-frontend/index.html index b484771aa1..2c097f785e 100644 --- a/docs/2.5.0/building-the-frontend/index.html +++ b/docs/2.5.0/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.5.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.5.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.5.0/contributing-guide/index.html b/docs/2.5.0/contributing-guide/index.html index 2bc8823129..b48b6c396a 100644 --- a/docs/2.5.0/contributing-guide/index.html +++ b/docs/2.5.0/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.5.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.5.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.5.0/css-guidelines/index.html b/docs/2.5.0/css-guidelines/index.html index 4ddb7a29c6..40eec2554f 100644 --- a/docs/2.5.0/css-guidelines/index.html +++ b/docs/2.5.0/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.5.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.5.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.5.0/discover/index.html b/docs/2.5.0/discover/index.html index 7bfed82571..d1ef577479 100644 --- a/docs/2.5.0/discover/index.html +++ b/docs/2.5.0/discover/index.html @@ -2,13 +2,13 @@ - -Getting started with Richie | Richie - - + +Getting started with Richie | Richie + + -
    Version: 2.5.0

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    +
    Version: 2.5.0

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    Login/password are admin/admin. The database is regularly flushed.

    Architecture

    Richie is a container-native application but can also be installed @@ -60,6 +60,6 @@

    Advanced - Connecting Richie to OpenEdx

    If you want users to enroll on courses in OpenEdx directly from Richie via API calls, you should read the advanced guide to connect -Richie to OpenEdx over TLS.

    +Richie to OpenEdx over TLS.

    \ No newline at end of file diff --git a/docs/2.5.0/django-react-interop/index.html b/docs/2.5.0/django-react-interop/index.html index 9fd6c14a89..10d4916dec 100644 --- a/docs/2.5.0/django-react-interop/index.html +++ b/docs/2.5.0/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.5.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.5.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -64,6 +64,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.5.0/docker-development/index.html b/docs/2.5.0/docker-development/index.html index f150d2c24d..20a1e395a0 100644 --- a/docs/2.5.0/docker-development/index.html +++ b/docs/2.5.0/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.5.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.5.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.5.0/frontend-overrides/index.html b/docs/2.5.0/frontend-overrides/index.html index f4597a839f..ccc0604ffb 100644 --- a/docs/2.5.0/frontend-overrides/index.html +++ b/docs/2.5.0/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.5.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.5.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.5.0/internationalization/index.html b/docs/2.5.0/internationalization/index.html index 4da770ab85..3cf1e3c139 100644 --- a/docs/2.5.0/internationalization/index.html +++ b/docs/2.5.0/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.5.0

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.5.0

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.5.0/lms-connection/index.html b/docs/2.5.0/lms-connection/index.html index 128ecd66d0..5840a4f2b6 100644 --- a/docs/2.5.0/lms-connection/index.html +++ b/docs/2.5.0/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with an LMS | Richie - - + +Connecting Richie with an LMS | Richie + + -
    Version: 2.5.0

    Connecting Richie with an LMS

    richie can be connected to one or more Learning Management Systems (LMS) like OpenEdx, Moodle +

    Version: 2.5.0

    Connecting Richie with an LMS

    richie can be connected to one or more Learning Management Systems (LMS) like OpenEdx, Moodle or Canvas for a seamless experience between browsing the course catalog on richie and following the course itself on the LMS.

    In order to connect richie with a LMS, there is an API bridge @@ -81,6 +81,6 @@

    https://richie.local.dev:8070 without browser warning about the certificate validity.

    You need to follow these steps once. If you want to use SSL later, just use make run-ssl to run OpenEdx and Richie apps. -Of course, you can still run apps without ssl by using make run.

    +Of course, you can still run apps without ssl by using make run.

    \ No newline at end of file diff --git a/docs/2.5.0/native-installation/index.html b/docs/2.5.0/native-installation/index.html index 0871d9afc9..1ae33849f4 100644 --- a/docs/2.5.0/native-installation/index.html +++ b/docs/2.5.0/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.5.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.5.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.6.0/accessibility-testing/index.html b/docs/2.6.0/accessibility-testing/index.html index 6066f5618a..d1a277e604 100644 --- a/docs/2.6.0/accessibility-testing/index.html +++ b/docs/2.6.0/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.6.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.6.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems in any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.6.0/building-the-frontend/index.html b/docs/2.6.0/building-the-frontend/index.html index 2179d22d87..b3f44e5a18 100644 --- a/docs/2.6.0/building-the-frontend/index.html +++ b/docs/2.6.0/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.6.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.6.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.6.0/contributing-guide/index.html b/docs/2.6.0/contributing-guide/index.html index 79ef378711..ae4f89102f 100644 --- a/docs/2.6.0/contributing-guide/index.html +++ b/docs/2.6.0/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.6.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.6.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.6.0/css-guidelines/index.html b/docs/2.6.0/css-guidelines/index.html index 5fd2ff631c..93d1df9dbf 100644 --- a/docs/2.6.0/css-guidelines/index.html +++ b/docs/2.6.0/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.6.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.6.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.6.0/discover/index.html b/docs/2.6.0/discover/index.html index c2be5a7d36..a229958893 100644 --- a/docs/2.6.0/discover/index.html +++ b/docs/2.6.0/discover/index.html @@ -2,13 +2,13 @@ - -Getting started with Richie | Richie - - + +Getting started with Richie | Richie + + -
    Version: 2.6.0

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    +
    Version: 2.6.0

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    Login/password are admin/admin. The database is regularly flushed.

    Architecture

    Richie is a container-native application but can also be installed @@ -60,6 +60,6 @@

    Advanced - Connecting Richie to OpenEdx

    If you want users to enroll on courses in OpenEdx directly from Richie via API calls, you should read the advanced guide to connect -Richie to OpenEdx over TLS.

    +Richie to OpenEdx over TLS.

    \ No newline at end of file diff --git a/docs/2.6.0/django-react-interop/index.html b/docs/2.6.0/django-react-interop/index.html index bb568bdd7d..58cd72df99 100644 --- a/docs/2.6.0/django-react-interop/index.html +++ b/docs/2.6.0/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.6.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.6.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -64,6 +64,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.6.0/docker-development/index.html b/docs/2.6.0/docker-development/index.html index 27eae54a7e..71b6f7996b 100644 --- a/docs/2.6.0/docker-development/index.html +++ b/docs/2.6.0/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.6.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.6.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.6.0/frontend-overrides/index.html b/docs/2.6.0/frontend-overrides/index.html index 27b68f8d98..d8539a76b3 100644 --- a/docs/2.6.0/frontend-overrides/index.html +++ b/docs/2.6.0/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.6.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.6.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.6.0/internationalization/index.html b/docs/2.6.0/internationalization/index.html index d3d33886a6..ddbba85c1f 100644 --- a/docs/2.6.0/internationalization/index.html +++ b/docs/2.6.0/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.6.0

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.6.0

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.6.0/lms-connection/index.html b/docs/2.6.0/lms-connection/index.html index 83bf08de03..6f03c509a9 100644 --- a/docs/2.6.0/lms-connection/index.html +++ b/docs/2.6.0/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with an LMS | Richie - - + +Connecting Richie with an LMS | Richie + + -
    Version: 2.6.0

    Connecting Richie with an LMS

    richie can be connected to one or more Learning Management Systems (LMS) like OpenEdx, Moodle +

    Version: 2.6.0

    Connecting Richie with an LMS

    richie can be connected to one or more Learning Management Systems (LMS) like OpenEdx, Moodle or Canvas for a seamless experience between browsing the course catalog on richie and following the course itself on the LMS.

    In order to connect richie with a LMS, there is an API bridge @@ -81,6 +81,6 @@

    https://richie.local.dev:8070 without browser warning about the certificate validity.

    You need to follow these steps once. If you want to use SSL later, just use make run-ssl to run OpenEdx and Richie apps. -Of course, you can still run apps without ssl by using make run.

    +Of course, you can still run apps without ssl by using make run.

    \ No newline at end of file diff --git a/docs/2.6.0/native-installation/index.html b/docs/2.6.0/native-installation/index.html index c5624004e4..446522c95c 100644 --- a/docs/2.6.0/native-installation/index.html +++ b/docs/2.6.0/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.6.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.6.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.7.0/accessibility-testing/index.html b/docs/2.7.0/accessibility-testing/index.html index 2ba94c949c..12aa5751d2 100644 --- a/docs/2.7.0/accessibility-testing/index.html +++ b/docs/2.7.0/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.7.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.7.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems in any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.7.0/building-the-frontend/index.html b/docs/2.7.0/building-the-frontend/index.html index 451f0ffcb4..1af2d0e3a4 100644 --- a/docs/2.7.0/building-the-frontend/index.html +++ b/docs/2.7.0/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.7.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.7.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.7.0/contributing-guide/index.html b/docs/2.7.0/contributing-guide/index.html index 620bc311be..4100ca39e7 100644 --- a/docs/2.7.0/contributing-guide/index.html +++ b/docs/2.7.0/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.7.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.7.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.7.0/css-guidelines/index.html b/docs/2.7.0/css-guidelines/index.html index f7290d28ea..f4cb7f215b 100644 --- a/docs/2.7.0/css-guidelines/index.html +++ b/docs/2.7.0/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.7.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.7.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.7.0/discover/index.html b/docs/2.7.0/discover/index.html index c199c845ee..3cebc2bdda 100644 --- a/docs/2.7.0/discover/index.html +++ b/docs/2.7.0/discover/index.html @@ -2,13 +2,13 @@ - -Getting started with Richie | Richie - - + +Getting started with Richie | Richie + + -
    Version: 2.7.0

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    +
    Version: 2.7.0

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    Login/password are admin/admin. The database is regularly flushed.

    Architecture

    Richie is a container-native application but can also be installed @@ -60,6 +60,6 @@

    Advanced - Connecting Richie to OpenEdx

    If you want users to enroll on courses in OpenEdx directly from Richie via API calls, you should read the advanced guide to connect -Richie to OpenEdx over TLS.

    +Richie to OpenEdx over TLS.

    \ No newline at end of file diff --git a/docs/2.7.0/django-react-interop/index.html b/docs/2.7.0/django-react-interop/index.html index f2d5689046..4c450b8735 100644 --- a/docs/2.7.0/django-react-interop/index.html +++ b/docs/2.7.0/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.7.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.7.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -64,6 +64,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.7.0/docker-development/index.html b/docs/2.7.0/docker-development/index.html index cb76ba85da..3009757f99 100644 --- a/docs/2.7.0/docker-development/index.html +++ b/docs/2.7.0/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.7.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.7.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.7.0/frontend-overrides/index.html b/docs/2.7.0/frontend-overrides/index.html index 95dbfc262d..d19d2761c7 100644 --- a/docs/2.7.0/frontend-overrides/index.html +++ b/docs/2.7.0/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.7.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.7.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.7.0/internationalization/index.html b/docs/2.7.0/internationalization/index.html index dc99ac01e6..f17e131e3d 100644 --- a/docs/2.7.0/internationalization/index.html +++ b/docs/2.7.0/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.7.0

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.7.0

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.7.0/lms-connection/index.html b/docs/2.7.0/lms-connection/index.html index 2ae14b2ce9..a57ebdfc34 100644 --- a/docs/2.7.0/lms-connection/index.html +++ b/docs/2.7.0/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with an LMS | Richie - - + +Connecting Richie with an LMS | Richie + + -
    Version: 2.7.0

    Connecting Richie with an LMS

    richie can be connected to one or more Learning Management Systems (LMS) like OpenEdx, Moodle +

    Version: 2.7.0

    Connecting Richie with an LMS

    richie can be connected to one or more Learning Management Systems (LMS) like OpenEdx, Moodle or Canvas for a seamless experience between browsing the course catalog on richie and following the course itself on the LMS.

    In order to connect richie with a LMS, there is an API bridge @@ -81,6 +81,6 @@

    https://richie.local.dev:8070 without browser warning about the certificate validity.

    You need to follow these steps once. If you want to use SSL later, just use make run-ssl to run OpenEdx and Richie apps. -Of course, you can still run apps without ssl by using make run.

    +Of course, you can still run apps without ssl by using make run.

    \ No newline at end of file diff --git a/docs/2.7.0/native-installation/index.html b/docs/2.7.0/native-installation/index.html index ad4bdc06eb..458e830121 100644 --- a/docs/2.7.0/native-installation/index.html +++ b/docs/2.7.0/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.7.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.7.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.7.1/accessibility-testing/index.html b/docs/2.7.1/accessibility-testing/index.html index e95dfc837e..910b78f6bb 100644 --- a/docs/2.7.1/accessibility-testing/index.html +++ b/docs/2.7.1/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.7.1

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.7.1

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems in any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.7.1/building-the-frontend/index.html b/docs/2.7.1/building-the-frontend/index.html index 3f17f32549..dfacc0bbd7 100644 --- a/docs/2.7.1/building-the-frontend/index.html +++ b/docs/2.7.1/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.7.1

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.7.1

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.7.1/contributing-guide/index.html b/docs/2.7.1/contributing-guide/index.html index b4b40222f7..3fed59d735 100644 --- a/docs/2.7.1/contributing-guide/index.html +++ b/docs/2.7.1/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.7.1

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.7.1

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.7.1/css-guidelines/index.html b/docs/2.7.1/css-guidelines/index.html index afb03cead0..f8480409f7 100644 --- a/docs/2.7.1/css-guidelines/index.html +++ b/docs/2.7.1/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.7.1

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.7.1

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.7.1/discover/index.html b/docs/2.7.1/discover/index.html index 59f22bed8e..0b8b5245b0 100644 --- a/docs/2.7.1/discover/index.html +++ b/docs/2.7.1/discover/index.html @@ -2,13 +2,13 @@ - -Getting started with Richie | Richie - - + +Getting started with Richie | Richie + + -
    Version: 2.7.1

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    +
    Version: 2.7.1

    Getting started with Richie

    If you're just looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    Login/password are admin/admin. The database is regularly flushed.

    Architecture

    Richie is a container-native application but can also be installed @@ -60,6 +60,6 @@

    Advanced - Connecting Richie to OpenEdx

    If you want users to enroll on courses in OpenEdx directly from Richie via API calls, you should read the advanced guide to connect -Richie to OpenEdx over TLS.

    +Richie to OpenEdx over TLS.

    \ No newline at end of file diff --git a/docs/2.7.1/django-react-interop/index.html b/docs/2.7.1/django-react-interop/index.html index 99bffe07c1..77556c027f 100644 --- a/docs/2.7.1/django-react-interop/index.html +++ b/docs/2.7.1/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.7.1

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.7.1

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -64,6 +64,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.7.1/docker-development/index.html b/docs/2.7.1/docker-development/index.html index b064d15c67..33875fc840 100644 --- a/docs/2.7.1/docker-development/index.html +++ b/docs/2.7.1/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.7.1

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.7.1

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.7.1/frontend-overrides/index.html b/docs/2.7.1/frontend-overrides/index.html index af1e0d292d..40ac37ef4b 100644 --- a/docs/2.7.1/frontend-overrides/index.html +++ b/docs/2.7.1/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.7.1

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.7.1

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.7.1/internationalization/index.html b/docs/2.7.1/internationalization/index.html index cc0ecb43e5..e85f1fc933 100644 --- a/docs/2.7.1/internationalization/index.html +++ b/docs/2.7.1/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.7.1

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.7.1

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.7.1/lms-connection/index.html b/docs/2.7.1/lms-connection/index.html index af46a317e5..011f06ba4d 100644 --- a/docs/2.7.1/lms-connection/index.html +++ b/docs/2.7.1/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with an LMS | Richie - - + +Connecting Richie with an LMS | Richie + + -
    Version: 2.7.1

    Connecting Richie with an LMS

    richie can be connected to one or more Learning Management Systems (LMS) like OpenEdx, Moodle +

    Version: 2.7.1

    Connecting Richie with an LMS

    richie can be connected to one or more Learning Management Systems (LMS) like OpenEdx, Moodle or Canvas for a seamless experience between browsing the course catalog on richie and following the course itself on the LMS.

    In order to connect richie with a LMS, there is an API bridge @@ -81,6 +81,6 @@

    https://richie.local.dev:8070 without browser warning about the certificate validity.

    You need to follow these steps once. If you want to use SSL later, just use make run-ssl to run OpenEdx and Richie apps. -Of course, you can still run apps without ssl by using make run.

    +Of course, you can still run apps without ssl by using make run.

    \ No newline at end of file diff --git a/docs/2.7.1/native-installation/index.html b/docs/2.7.1/native-installation/index.html index 4ca99cadb7..fdd44669bc 100644 --- a/docs/2.7.1/native-installation/index.html +++ b/docs/2.7.1/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.7.1

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.7.1

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.8.0/accessibility-testing/index.html b/docs/2.8.0/accessibility-testing/index.html index 0f470f7f2c..2bcdfc8bd5 100644 --- a/docs/2.8.0/accessibility-testing/index.html +++ b/docs/2.8.0/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.8.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.8.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems in any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.8.0/api/course-run-synchronization-api/index.html b/docs/2.8.0/api/course-run-synchronization-api/index.html index 9e9af877e5..3dd47dbe09 100644 --- a/docs/2.8.0/api/course-run-synchronization-api/index.html +++ b/docs/2.8.0/api/course-run-synchronization-api/index.html @@ -2,10 +2,10 @@ - -Course run synchronization API | Richie - - + +Course run synchronization API | Richie + +
    Version: 2.8.0

    Course run synchronization API

    API endpoint allowing remote systems to synchronize their course runs with a Richie instance.

    @@ -52,6 +52,6 @@

    +
    \ No newline at end of file diff --git a/docs/2.8.0/building-the-frontend/index.html b/docs/2.8.0/building-the-frontend/index.html index c88a2ec768..ad59e3c69a 100644 --- a/docs/2.8.0/building-the-frontend/index.html +++ b/docs/2.8.0/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.8.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.8.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.8.0/contributing-guide/index.html b/docs/2.8.0/contributing-guide/index.html index 03b9477511..378b059156 100644 --- a/docs/2.8.0/contributing-guide/index.html +++ b/docs/2.8.0/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.8.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.8.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.8.0/css-guidelines/index.html b/docs/2.8.0/css-guidelines/index.html index 904e3d38ee..bb048a97ba 100644 --- a/docs/2.8.0/css-guidelines/index.html +++ b/docs/2.8.0/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.8.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.8.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.8.0/discover/index.html b/docs/2.8.0/discover/index.html index 39cae49338..32c244d7a1 100644 --- a/docs/2.8.0/discover/index.html +++ b/docs/2.8.0/discover/index.html @@ -2,13 +2,13 @@ - -Getting started with Richie | Richie - - + +Getting started with Richie | Richie + + -
    Version: 2.8.0

    Getting started with Richie

    If you're looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    +
    Version: 2.8.0

    Getting started with Richie

    If you're looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    Login/password are admin/admin. The database is regularly flushed.

    Architecture

    Richie is a container-native application but can also be installed @@ -55,6 +55,6 @@

    This approach is used for example on https://www.fun-campus.fr or https://catalogue.edulib.org.

    For a seamless user experience, it is possible to connect a Richie instance to an OpenEdX instance (or some other LMS like Moodle at the cost of minor adaptations), in several ways that we explain in -the LMS connection guide.

    +the LMS connection guide.

    \ No newline at end of file diff --git a/docs/2.8.0/displaying-connection-status/index.html b/docs/2.8.0/displaying-connection-status/index.html index 9d77526a16..a56be5ff21 100644 --- a/docs/2.8.0/displaying-connection-status/index.html +++ b/docs/2.8.0/displaying-connection-status/index.html @@ -2,10 +2,10 @@ - -Displaying OpenEdX connection status in Richie | Richie - - + +Displaying OpenEdX connection status in Richie | Richie + + +
    \ No newline at end of file diff --git a/docs/2.8.0/django-react-interop/index.html b/docs/2.8.0/django-react-interop/index.html index ccd297de2c..7ca266c058 100644 --- a/docs/2.8.0/django-react-interop/index.html +++ b/docs/2.8.0/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.8.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.8.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -64,6 +64,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.8.0/docker-development/index.html b/docs/2.8.0/docker-development/index.html index 674f1413aa..60dacbfbc4 100644 --- a/docs/2.8.0/docker-development/index.html +++ b/docs/2.8.0/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.8.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.8.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.8.0/frontend-overrides/index.html b/docs/2.8.0/frontend-overrides/index.html index 62c1295a01..47b1b30ee6 100644 --- a/docs/2.8.0/frontend-overrides/index.html +++ b/docs/2.8.0/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.8.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.8.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.8.0/internationalization/index.html b/docs/2.8.0/internationalization/index.html index 4df3b2d383..393da85637 100644 --- a/docs/2.8.0/internationalization/index.html +++ b/docs/2.8.0/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.8.0

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.8.0

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.8.0/lms-backends/index.html b/docs/2.8.0/lms-backends/index.html index 3e7441c648..519633ab92 100644 --- a/docs/2.8.0/lms-backends/index.html +++ b/docs/2.8.0/lms-backends/index.html @@ -2,10 +2,10 @@ - -Configuring LMS Backends | Richie - - + +Configuring LMS Backends | Richie + +
    Version: 2.8.0

    Configuring LMS Backends

    Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless @@ -115,6 +115,6 @@

    Technical

    If you encounter an issue with this documentation or the backends included in Richie, please open an issue on our repository.

    If you need a custom backend, you can submit a PR or -open an issue and we will consider adding it.

    +open an issue and we will consider adding it.

    \ No newline at end of file diff --git a/docs/2.8.0/lms-connection/index.html b/docs/2.8.0/lms-connection/index.html index da6a5e0afb..7080e00329 100644 --- a/docs/2.8.0/lms-connection/index.html +++ b/docs/2.8.0/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with one or more LMS | Richie - - + +Connecting Richie with one or more LMS | Richie + + -
    Version: 2.8.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    +
    Version: 2.8.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    Richie can be connected to an LMS in several ways, ranging from SSO to a fully integrated seamless experience.

    As of today, each approach has been implemented for OpenEdX but the same could be done for @@ -63,6 +63,6 @@

    Development

    If you want to activate seamless enrollment locally for development, you will need to set up TLS domains for both Richie and OpenEdX. To do this, head over to our -guide on setting-up TLS connections for Richie and OpenEdX.

    +guide on setting-up TLS connections for Richie and OpenEdX.

    \ No newline at end of file diff --git a/docs/2.8.0/native-installation/index.html b/docs/2.8.0/native-installation/index.html index e31b0ee941..22511a87b2 100644 --- a/docs/2.8.0/native-installation/index.html +++ b/docs/2.8.0/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.8.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.8.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.8.0/synchronizing-course-runs/index.html b/docs/2.8.0/synchronizing-course-runs/index.html index b3b24dbce6..463e56439e 100644 --- a/docs/2.8.0/synchronizing-course-runs/index.html +++ b/docs/2.8.0/synchronizing-course-runs/index.html @@ -2,10 +2,10 @@ - -Synchronizing course runs between Richie and OpenEdX | Richie - - + +Synchronizing course runs between Richie and OpenEdX | Richie + +
    Version: 2.8.0

    Synchronizing course runs between Richie and OpenEdX

    Richie can receive automatic course runs updates on a dedicated API endpoint.

    @@ -49,6 +49,6 @@

    import hashlib
    import hmac
    import json

    from django.conf import settings

    from microsite_configuration import microsite
    import requests
    from xmodule.modulestore.django import modulestore


    def update_course(course_key, *args, **kwargs):
    """Synchronize an OpenEdX course, identified by its course key, with a Richie instance."""
    course = modulestore().get_course(course_key)
    edxapp_domain = microsite.get_value("site_domain", settings.LMS_BASE)

    data = {
    "resource_link": "https://{:s}/courses/{!s}/info".format(
    edxapp_domain, course_key
    ),
    "start": course.start and course.start.isoformat(),
    "end": course.end and course.end.isoformat(),
    "enrollment_start": course.enrollment_start and course.enrollment_start.isoformat(),
    "enrollment_end": course.enrollment_end and course.enrollment_end.isoformat(),
    "languages": [course.language or settings.LANGUAGE_CODE],
    }

    signature = hmac.new(
    setting.COURSE_HOOK["secret"].encode("utf-8"),
    msg=json.dumps(data).encode("utf-8"),
    digestmod=hashlib.sha256,
    ).hexdigest()

    response = requests.post(
    setting.COURSE_HOOK["url"],
    json=data,
    headers={"Authorization": "SIG-HMAC-SHA256 {:s}".format(signature)},
    )

    Thanks to the signal emitted in OpenEdX, this function can then be triggered each time a course is modified and published:

    -
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    +
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    \ No newline at end of file diff --git a/docs/2.8.0/tls-connection/index.html b/docs/2.8.0/tls-connection/index.html index 20d89c6301..1aa8cb033d 100644 --- a/docs/2.8.0/tls-connection/index.html +++ b/docs/2.8.0/tls-connection/index.html @@ -2,10 +2,10 @@ - -Connecting Richie and OpenEdX over TLS for development | Richie - - + +Connecting Richie and OpenEdX over TLS for development | Richie + +
    Version: 2.8.0

    Connecting Richie and OpenEdX over TLS for development

    Purpose

    @@ -68,6 +68,6 @@

    $ make run-ssl

    Of course, you can still run apps without ssl by using:

    -
    $ make run
    +
    $ make run
    \ No newline at end of file diff --git a/docs/2.8.0/web-analytics/index.html b/docs/2.8.0/web-analytics/index.html index 8cd4774e1c..18ebc6ecaa 100644 --- a/docs/2.8.0/web-analytics/index.html +++ b/docs/2.8.0/web-analytics/index.html @@ -2,10 +2,10 @@ - -Add web analytics to your site | Richie - - + +Add web analytics to your site | Richie + +
    Version: 2.8.0

    Add web analytics to your site

    The purpose of this file is to document how you can enable a Web Analytics solution. @@ -53,6 +53,6 @@

    <script type="text/javascript">
    console.log("organization codes: '{{ WEB_ANALYTICS.DIMENSIONS.organizations_codes |join:" | " }}");
    </script>

    +
    <script type="text/javascript">
    console.log("organization codes: '{{ WEB_ANALYTICS.DIMENSIONS.organizations_codes |join:" | " }}");
    </script>
    \ No newline at end of file diff --git a/docs/2.8.1/accessibility-testing/index.html b/docs/2.8.1/accessibility-testing/index.html index 4e6fc9a734..d22bb80d8a 100644 --- a/docs/2.8.1/accessibility-testing/index.html +++ b/docs/2.8.1/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.8.1

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.8.1

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems in any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.8.1/api/course-run-synchronization-api/index.html b/docs/2.8.1/api/course-run-synchronization-api/index.html index f8b68c03c8..609e2a6282 100644 --- a/docs/2.8.1/api/course-run-synchronization-api/index.html +++ b/docs/2.8.1/api/course-run-synchronization-api/index.html @@ -2,10 +2,10 @@ - -Course run synchronization API | Richie - - + +Course run synchronization API | Richie + +
    Version: 2.8.1

    Course run synchronization API

    API endpoint allowing remote systems to synchronize their course runs with a Richie instance.

    @@ -52,6 +52,6 @@

    +
    \ No newline at end of file diff --git a/docs/2.8.1/building-the-frontend/index.html b/docs/2.8.1/building-the-frontend/index.html index a5e8a35a0c..f5d4c91506 100644 --- a/docs/2.8.1/building-the-frontend/index.html +++ b/docs/2.8.1/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.8.1

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.8.1

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.8.1/contributing-guide/index.html b/docs/2.8.1/contributing-guide/index.html index 2e8b800489..dbd44cd7b1 100644 --- a/docs/2.8.1/contributing-guide/index.html +++ b/docs/2.8.1/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.8.1

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.8.1

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.8.1/css-guidelines/index.html b/docs/2.8.1/css-guidelines/index.html index 66c6a7ecf5..5646ff4982 100644 --- a/docs/2.8.1/css-guidelines/index.html +++ b/docs/2.8.1/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.8.1

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.8.1

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.8.1/discover/index.html b/docs/2.8.1/discover/index.html index 394d0b240f..429f5dfb64 100644 --- a/docs/2.8.1/discover/index.html +++ b/docs/2.8.1/discover/index.html @@ -2,13 +2,13 @@ - -Getting started with Richie | Richie - - + +Getting started with Richie | Richie + + -
    Version: 2.8.1

    Getting started with Richie

    If you're looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    +
    Version: 2.8.1

    Getting started with Richie

    If you're looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    Login/password are admin/admin. The database is regularly flushed.

    Architecture

    Richie is a container-native application but can also be installed @@ -55,6 +55,6 @@

    This approach is used for example on https://www.fun-campus.fr or https://catalogue.edulib.org.

    For a seamless user experience, it is possible to connect a Richie instance to an OpenEdX instance (or some other LMS like Moodle at the cost of minor adaptations), in several ways that we explain in -the LMS connection guide.

    +the LMS connection guide.

    \ No newline at end of file diff --git a/docs/2.8.1/displaying-connection-status/index.html b/docs/2.8.1/displaying-connection-status/index.html index d1ee52c8a2..a61ca1729b 100644 --- a/docs/2.8.1/displaying-connection-status/index.html +++ b/docs/2.8.1/displaying-connection-status/index.html @@ -2,10 +2,10 @@ - -Displaying OpenEdX connection status in Richie | Richie - - + +Displaying OpenEdX connection status in Richie | Richie + + +
    \ No newline at end of file diff --git a/docs/2.8.1/django-react-interop/index.html b/docs/2.8.1/django-react-interop/index.html index d78f84e971..2f32ae7e7b 100644 --- a/docs/2.8.1/django-react-interop/index.html +++ b/docs/2.8.1/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.8.1

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.8.1

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -64,6 +64,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.8.1/docker-development/index.html b/docs/2.8.1/docker-development/index.html index 1d3c8e3808..e45e61cd41 100644 --- a/docs/2.8.1/docker-development/index.html +++ b/docs/2.8.1/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.8.1

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.8.1

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.8.1/frontend-overrides/index.html b/docs/2.8.1/frontend-overrides/index.html index 5ec146c8fe..4e63b7a61f 100644 --- a/docs/2.8.1/frontend-overrides/index.html +++ b/docs/2.8.1/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.8.1

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.8.1

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.8.1/internationalization/index.html b/docs/2.8.1/internationalization/index.html index af709239c9..7305227d17 100644 --- a/docs/2.8.1/internationalization/index.html +++ b/docs/2.8.1/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.8.1

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.8.1

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.8.1/lms-backends/index.html b/docs/2.8.1/lms-backends/index.html index 1b99f9542a..f05dbe4fc8 100644 --- a/docs/2.8.1/lms-backends/index.html +++ b/docs/2.8.1/lms-backends/index.html @@ -2,10 +2,10 @@ - -Configuring LMS Backends | Richie - - + +Configuring LMS Backends | Richie + +
    Version: 2.8.1

    Configuring LMS Backends

    Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless @@ -115,6 +115,6 @@

    Technical

    If you encounter an issue with this documentation or the backends included in Richie, please open an issue on our repository.

    If you need a custom backend, you can submit a PR or -open an issue and we will consider adding it.

    +open an issue and we will consider adding it.

    \ No newline at end of file diff --git a/docs/2.8.1/lms-connection/index.html b/docs/2.8.1/lms-connection/index.html index 05a4ba6817..1a0639d75e 100644 --- a/docs/2.8.1/lms-connection/index.html +++ b/docs/2.8.1/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with one or more LMS | Richie - - + +Connecting Richie with one or more LMS | Richie + + -
    Version: 2.8.1

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    +
    Version: 2.8.1

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    Richie can be connected to an LMS in several ways, ranging from SSO to a fully integrated seamless experience.

    As of today, each approach has been implemented for OpenEdX but the same could be done for @@ -63,6 +63,6 @@

    Development

    If you want to activate seamless enrollment locally for development, you will need to set up TLS domains for both Richie and OpenEdX. To do this, head over to our -guide on setting-up TLS connections for Richie and OpenEdX.

    +guide on setting-up TLS connections for Richie and OpenEdX.

    \ No newline at end of file diff --git a/docs/2.8.1/native-installation/index.html b/docs/2.8.1/native-installation/index.html index d65beb55c8..7b1a776e62 100644 --- a/docs/2.8.1/native-installation/index.html +++ b/docs/2.8.1/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.8.1

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.8.1

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.8.1/synchronizing-course-runs/index.html b/docs/2.8.1/synchronizing-course-runs/index.html index 8ae6a17223..ac33dae090 100644 --- a/docs/2.8.1/synchronizing-course-runs/index.html +++ b/docs/2.8.1/synchronizing-course-runs/index.html @@ -2,10 +2,10 @@ - -Synchronizing course runs between Richie and OpenEdX | Richie - - + +Synchronizing course runs between Richie and OpenEdX | Richie + +
    Version: 2.8.1

    Synchronizing course runs between Richie and OpenEdX

    Richie can receive automatic course runs updates on a dedicated API endpoint.

    @@ -49,6 +49,6 @@

    import hashlib
    import hmac
    import json

    from django.conf import settings

    from microsite_configuration import microsite
    import requests
    from xmodule.modulestore.django import modulestore


    def update_course(course_key, *args, **kwargs):
    """Synchronize an OpenEdX course, identified by its course key, with a Richie instance."""
    course = modulestore().get_course(course_key)
    edxapp_domain = microsite.get_value("site_domain", settings.LMS_BASE)

    data = {
    "resource_link": "https://{:s}/courses/{!s}/info".format(
    edxapp_domain, course_key
    ),
    "start": course.start and course.start.isoformat(),
    "end": course.end and course.end.isoformat(),
    "enrollment_start": course.enrollment_start and course.enrollment_start.isoformat(),
    "enrollment_end": course.enrollment_end and course.enrollment_end.isoformat(),
    "languages": [course.language or settings.LANGUAGE_CODE],
    }

    signature = hmac.new(
    setting.COURSE_HOOK["secret"].encode("utf-8"),
    msg=json.dumps(data).encode("utf-8"),
    digestmod=hashlib.sha256,
    ).hexdigest()

    response = requests.post(
    setting.COURSE_HOOK["url"],
    json=data,
    headers={"Authorization": "SIG-HMAC-SHA256 {:s}".format(signature)},
    )

    Thanks to the signal emitted in OpenEdX, this function can then be triggered each time a course is modified and published:

    -
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    +
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    \ No newline at end of file diff --git a/docs/2.8.1/tls-connection/index.html b/docs/2.8.1/tls-connection/index.html index dec2cbf95f..1fa43df271 100644 --- a/docs/2.8.1/tls-connection/index.html +++ b/docs/2.8.1/tls-connection/index.html @@ -2,10 +2,10 @@ - -Connecting Richie and OpenEdX over TLS for development | Richie - - + +Connecting Richie and OpenEdX over TLS for development | Richie + +
    Version: 2.8.1

    Connecting Richie and OpenEdX over TLS for development

    Purpose

    @@ -68,6 +68,6 @@

    $ make run-ssl

    Of course, you can still run apps without ssl by using:

    -
    $ make run
    +
    $ make run
    \ No newline at end of file diff --git a/docs/2.8.1/web-analytics/index.html b/docs/2.8.1/web-analytics/index.html index 8a39508353..e97301f55f 100644 --- a/docs/2.8.1/web-analytics/index.html +++ b/docs/2.8.1/web-analytics/index.html @@ -2,13 +2,13 @@ - -Add web analytics to your site | Richie - - + +Add web analytics to your site | Richie + + -
    Version: 2.8.1

    Add web analytics to your site

    The purpose of this file is to document how you can enable a Web Analytics solution. +

    Version: 2.8.1

    Add web analytics to your site

    The purpose of this file is to document how you can enable a Web Analytics solution. Currently Richie only supports by default the Google Analytics using the Google Tag Manager Javascript. But it is possible with little cost to add support for other web analytics solutions.

    Google Analytics

    @@ -53,6 +53,6 @@

    <script type="text/javascript">
    console.log("organization codes: '{{ WEB_ANALYTICS.DIMENSIONS.organizations_codes |join:" | " }}");
    </script>

    +
    <script type="text/javascript">
    console.log("organization codes: '{{ WEB_ANALYTICS.DIMENSIONS.organizations_codes |join:" | " }}");
    </script>
    \ No newline at end of file diff --git a/docs/2.8.2/accessibility-testing/index.html b/docs/2.8.2/accessibility-testing/index.html index d4af6d4aeb..78d2e75f9a 100644 --- a/docs/2.8.2/accessibility-testing/index.html +++ b/docs/2.8.2/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.8.2

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.8.2

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems in any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.8.2/api/course-run-synchronization-api/index.html b/docs/2.8.2/api/course-run-synchronization-api/index.html index 7b9f1fd49c..7c1975fc89 100644 --- a/docs/2.8.2/api/course-run-synchronization-api/index.html +++ b/docs/2.8.2/api/course-run-synchronization-api/index.html @@ -2,10 +2,10 @@ - -Course run synchronization API | Richie - - + +Course run synchronization API | Richie + +
    Version: 2.8.2

    Course run synchronization API

    API endpoint allowing remote systems to synchronize their course runs with a Richie instance.

    @@ -52,6 +52,6 @@

    +
    \ No newline at end of file diff --git a/docs/2.8.2/building-the-frontend/index.html b/docs/2.8.2/building-the-frontend/index.html index 2de98b020f..10f78bfb7c 100644 --- a/docs/2.8.2/building-the-frontend/index.html +++ b/docs/2.8.2/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.8.2

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.8.2

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.8.2/contributing-guide/index.html b/docs/2.8.2/contributing-guide/index.html index 145821e561..106c932780 100644 --- a/docs/2.8.2/contributing-guide/index.html +++ b/docs/2.8.2/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.8.2

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.8.2

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.8.2/css-guidelines/index.html b/docs/2.8.2/css-guidelines/index.html index aaa5b4a601..1519f3834a 100644 --- a/docs/2.8.2/css-guidelines/index.html +++ b/docs/2.8.2/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.8.2

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.8.2

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.8.2/discover/index.html b/docs/2.8.2/discover/index.html index e6a9b68705..b6ec5f57ae 100644 --- a/docs/2.8.2/discover/index.html +++ b/docs/2.8.2/discover/index.html @@ -2,13 +2,13 @@ - -Getting started with Richie | Richie - - + +Getting started with Richie | Richie + + -
    Version: 2.8.2

    Getting started with Richie

    If you're looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    +
    Version: 2.8.2

    Getting started with Richie

    If you're looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    Login/password are admin/admin. The database is regularly flushed.

    Architecture

    Richie is a container-native application but can also be installed @@ -55,6 +55,6 @@

    This approach is used for example on https://www.fun-campus.fr or https://catalogue.edulib.org.

    For a seamless user experience, it is possible to connect a Richie instance to an OpenEdX instance (or some other LMS like Moodle at the cost of minor adaptations), in several ways that we explain in -the LMS connection guide.

    +the LMS connection guide.

    \ No newline at end of file diff --git a/docs/2.8.2/displaying-connection-status/index.html b/docs/2.8.2/displaying-connection-status/index.html index f2cd3188af..0e7fc0b9e9 100644 --- a/docs/2.8.2/displaying-connection-status/index.html +++ b/docs/2.8.2/displaying-connection-status/index.html @@ -2,10 +2,10 @@ - -Displaying OpenEdX connection status in Richie | Richie - - + +Displaying OpenEdX connection status in Richie | Richie + + +
    \ No newline at end of file diff --git a/docs/2.8.2/django-react-interop/index.html b/docs/2.8.2/django-react-interop/index.html index dbbf3d08bb..5d7f511f65 100644 --- a/docs/2.8.2/django-react-interop/index.html +++ b/docs/2.8.2/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.8.2

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.8.2

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -64,6 +64,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.8.2/docker-development/index.html b/docs/2.8.2/docker-development/index.html index 7810a6b4b5..f1fe65557f 100644 --- a/docs/2.8.2/docker-development/index.html +++ b/docs/2.8.2/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.8.2

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.8.2

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.8.2/frontend-overrides/index.html b/docs/2.8.2/frontend-overrides/index.html index 08f928a7d8..4c224b6ce7 100644 --- a/docs/2.8.2/frontend-overrides/index.html +++ b/docs/2.8.2/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.8.2

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.8.2

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.8.2/internationalization/index.html b/docs/2.8.2/internationalization/index.html index bb1ab47e46..bfbf0f75c9 100644 --- a/docs/2.8.2/internationalization/index.html +++ b/docs/2.8.2/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.8.2

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.8.2

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.8.2/lms-backends/index.html b/docs/2.8.2/lms-backends/index.html index 4440a09724..6851dea1d6 100644 --- a/docs/2.8.2/lms-backends/index.html +++ b/docs/2.8.2/lms-backends/index.html @@ -2,10 +2,10 @@ - -Configuring LMS Backends | Richie - - + +Configuring LMS Backends | Richie + +
    Version: 2.8.2

    Configuring LMS Backends

    Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless @@ -115,6 +115,6 @@

    Technical

    If you encounter an issue with this documentation or the backends included in Richie, please open an issue on our repository.

    If you need a custom backend, you can submit a PR or -open an issue and we will consider adding it.

    +open an issue and we will consider adding it.

    \ No newline at end of file diff --git a/docs/2.8.2/lms-connection/index.html b/docs/2.8.2/lms-connection/index.html index 6b8abd919f..00ec086fbb 100644 --- a/docs/2.8.2/lms-connection/index.html +++ b/docs/2.8.2/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with one or more LMS | Richie - - + +Connecting Richie with one or more LMS | Richie + + -
    Version: 2.8.2

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    +
    Version: 2.8.2

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    Richie can be connected to an LMS in several ways, ranging from SSO to a fully integrated seamless experience.

    As of today, each approach has been implemented for OpenEdX but the same could be done for @@ -63,6 +63,6 @@

    Development

    If you want to activate seamless enrollment locally for development, you will need to set up TLS domains for both Richie and OpenEdX. To do this, head over to our -guide on setting-up TLS connections for Richie and OpenEdX.

    +guide on setting-up TLS connections for Richie and OpenEdX.

    \ No newline at end of file diff --git a/docs/2.8.2/native-installation/index.html b/docs/2.8.2/native-installation/index.html index 9fac1fc9a0..fff701d9d9 100644 --- a/docs/2.8.2/native-installation/index.html +++ b/docs/2.8.2/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.8.2

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.8.2

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.8.2/synchronizing-course-runs/index.html b/docs/2.8.2/synchronizing-course-runs/index.html index 919011d43b..79aaf672f8 100644 --- a/docs/2.8.2/synchronizing-course-runs/index.html +++ b/docs/2.8.2/synchronizing-course-runs/index.html @@ -2,10 +2,10 @@ - -Synchronizing course runs between Richie and OpenEdX | Richie - - + +Synchronizing course runs between Richie and OpenEdX | Richie + +
    Version: 2.8.2

    Synchronizing course runs between Richie and OpenEdX

    Richie can receive automatic course runs updates on a dedicated API endpoint.

    @@ -49,6 +49,6 @@

    import hashlib
    import hmac
    import json

    from django.conf import settings

    from microsite_configuration import microsite
    import requests
    from xmodule.modulestore.django import modulestore


    def update_course(course_key, *args, **kwargs):
    """Synchronize an OpenEdX course, identified by its course key, with a Richie instance."""
    course = modulestore().get_course(course_key)
    edxapp_domain = microsite.get_value("site_domain", settings.LMS_BASE)

    data = {
    "resource_link": "https://{:s}/courses/{!s}/info".format(
    edxapp_domain, course_key
    ),
    "start": course.start and course.start.isoformat(),
    "end": course.end and course.end.isoformat(),
    "enrollment_start": course.enrollment_start and course.enrollment_start.isoformat(),
    "enrollment_end": course.enrollment_end and course.enrollment_end.isoformat(),
    "languages": [course.language or settings.LANGUAGE_CODE],
    }

    signature = hmac.new(
    setting.COURSE_HOOK["secret"].encode("utf-8"),
    msg=json.dumps(data).encode("utf-8"),
    digestmod=hashlib.sha256,
    ).hexdigest()

    response = requests.post(
    setting.COURSE_HOOK["url"],
    json=data,
    headers={"Authorization": "SIG-HMAC-SHA256 {:s}".format(signature)},
    )

    Thanks to the signal emitted in OpenEdX, this function can then be triggered each time a course is modified and published:

    -
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    +
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    \ No newline at end of file diff --git a/docs/2.8.2/tls-connection/index.html b/docs/2.8.2/tls-connection/index.html index 68c79b320c..9d1a34ba49 100644 --- a/docs/2.8.2/tls-connection/index.html +++ b/docs/2.8.2/tls-connection/index.html @@ -2,10 +2,10 @@ - -Connecting Richie and OpenEdX over TLS for development | Richie - - + +Connecting Richie and OpenEdX over TLS for development | Richie + +
    Version: 2.8.2

    Connecting Richie and OpenEdX over TLS for development

    Purpose

    @@ -68,6 +68,6 @@

    $ make run-ssl

    Of course, you can still run apps without ssl by using:

    -
    $ make run
    +
    $ make run
    \ No newline at end of file diff --git a/docs/2.8.2/web-analytics/index.html b/docs/2.8.2/web-analytics/index.html index 2604a5c6c6..55061c52a4 100644 --- a/docs/2.8.2/web-analytics/index.html +++ b/docs/2.8.2/web-analytics/index.html @@ -2,13 +2,13 @@ - -Add web analytics to your site | Richie - - + +Add web analytics to your site | Richie + + -
    Version: 2.8.2

    Add web analytics to your site

    The purpose of this file is to document how you can enable a Web Analytics solution. +

    Version: 2.8.2

    Add web analytics to your site

    The purpose of this file is to document how you can enable a Web Analytics solution. Currently Richie only supports by default the Google Analytics using the Google Tag Manager Javascript. But it is possible with little cost to add support for other web analytics solutions.

    Google Analytics

    @@ -53,6 +53,6 @@

    <script type="text/javascript">
    console.log("organization codes: '{{ WEB_ANALYTICS.DIMENSIONS.organizations_codes |join:" | " }}");
    </script>

    +
    <script type="text/javascript">
    console.log("organization codes: '{{ WEB_ANALYTICS.DIMENSIONS.organizations_codes |join:" | " }}");
    </script>
    \ No newline at end of file diff --git a/docs/2.9.0/accessibility-testing/index.html b/docs/2.9.0/accessibility-testing/index.html index 7bde544a0b..b4087a516b 100644 --- a/docs/2.9.0/accessibility-testing/index.html +++ b/docs/2.9.0/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.9.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.9.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems in any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.9.0/api/course-run-synchronization-api/index.html b/docs/2.9.0/api/course-run-synchronization-api/index.html index e4f640af39..60a90ee761 100644 --- a/docs/2.9.0/api/course-run-synchronization-api/index.html +++ b/docs/2.9.0/api/course-run-synchronization-api/index.html @@ -2,10 +2,10 @@ - -Course run synchronization API | Richie - - + +Course run synchronization API | Richie + +
    Version: 2.9.0

    Course run synchronization API

    API endpoint allowing remote systems to synchronize their course runs with a Richie instance.

    @@ -52,6 +52,6 @@

    +
    \ No newline at end of file diff --git a/docs/2.9.0/building-the-frontend/index.html b/docs/2.9.0/building-the-frontend/index.html index f8d388e867..da8849719d 100644 --- a/docs/2.9.0/building-the-frontend/index.html +++ b/docs/2.9.0/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.9.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.9.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.9.0/contributing-guide/index.html b/docs/2.9.0/contributing-guide/index.html index 0ce156e19f..d8930729ff 100644 --- a/docs/2.9.0/contributing-guide/index.html +++ b/docs/2.9.0/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.9.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.9.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.9.0/css-guidelines/index.html b/docs/2.9.0/css-guidelines/index.html index e6ed8031cb..c575970085 100644 --- a/docs/2.9.0/css-guidelines/index.html +++ b/docs/2.9.0/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.9.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.9.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.9.0/discover/index.html b/docs/2.9.0/discover/index.html index ec5a907113..15e402ce49 100644 --- a/docs/2.9.0/discover/index.html +++ b/docs/2.9.0/discover/index.html @@ -2,13 +2,13 @@ - -Getting started with Richie | Richie - - + +Getting started with Richie | Richie + + -
    Version: 2.9.0

    Getting started with Richie

    If you're looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    +
    Version: 2.9.0

    Getting started with Richie

    If you're looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    Login/password are admin/admin. The database is regularly flushed.

    Architecture

    Richie is a container-native application but can also be installed @@ -55,6 +55,6 @@

    This approach is used for example on https://www.fun-campus.fr or https://catalogue.edulib.org.

    For a seamless user experience, it is possible to connect a Richie instance to an OpenEdX instance (or some other LMS like Moodle at the cost of minor adaptations), in several ways that we explain in -the LMS connection guide.

    +the LMS connection guide.

    \ No newline at end of file diff --git a/docs/2.9.0/displaying-connection-status/index.html b/docs/2.9.0/displaying-connection-status/index.html index d827e6430c..d40b28861e 100644 --- a/docs/2.9.0/displaying-connection-status/index.html +++ b/docs/2.9.0/displaying-connection-status/index.html @@ -2,10 +2,10 @@ - -Displaying OpenEdX connection status in Richie | Richie - - + +Displaying OpenEdX connection status in Richie | Richie + + +
    \ No newline at end of file diff --git a/docs/2.9.0/django-react-interop/index.html b/docs/2.9.0/django-react-interop/index.html index bf524ecfdb..99474d594f 100644 --- a/docs/2.9.0/django-react-interop/index.html +++ b/docs/2.9.0/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.9.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.9.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -64,6 +64,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.9.0/docker-development/index.html b/docs/2.9.0/docker-development/index.html index 1e5de46ca4..efc7fc9191 100644 --- a/docs/2.9.0/docker-development/index.html +++ b/docs/2.9.0/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.9.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.9.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.9.0/frontend-overrides/index.html b/docs/2.9.0/frontend-overrides/index.html index fe3c2374a7..59a03cbbad 100644 --- a/docs/2.9.0/frontend-overrides/index.html +++ b/docs/2.9.0/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.9.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.9.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.9.0/internationalization/index.html b/docs/2.9.0/internationalization/index.html index 2277047fb0..18cd1deef8 100644 --- a/docs/2.9.0/internationalization/index.html +++ b/docs/2.9.0/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.9.0

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.9.0

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.9.0/lms-backends/index.html b/docs/2.9.0/lms-backends/index.html index af314594ef..a8bf55021b 100644 --- a/docs/2.9.0/lms-backends/index.html +++ b/docs/2.9.0/lms-backends/index.html @@ -2,10 +2,10 @@ - -Configuring LMS Backends | Richie - - + +Configuring LMS Backends | Richie + +
    Version: 2.9.0

    Configuring LMS Backends

    Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless @@ -115,6 +115,6 @@

    Technical

    If you encounter an issue with this documentation or the backends included in Richie, please open an issue on our repository.

    If you need a custom backend, you can submit a PR or -open an issue and we will consider adding it.

    +open an issue and we will consider adding it.

    \ No newline at end of file diff --git a/docs/2.9.0/lms-connection/index.html b/docs/2.9.0/lms-connection/index.html index 73edcea818..535f906e7d 100644 --- a/docs/2.9.0/lms-connection/index.html +++ b/docs/2.9.0/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with one or more LMS | Richie - - + +Connecting Richie with one or more LMS | Richie + + -
    Version: 2.9.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    +
    Version: 2.9.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    Richie can be connected to an LMS in several ways, ranging from SSO to a fully integrated seamless experience.

    As of today, each approach has been implemented for OpenEdX but the same could be done for @@ -63,6 +63,6 @@

    Development

    If you want to activate seamless enrollment locally for development, you will need to set up TLS domains for both Richie and OpenEdX. To do this, head over to our -guide on setting-up TLS connections for Richie and OpenEdX.

    +guide on setting-up TLS connections for Richie and OpenEdX.

    \ No newline at end of file diff --git a/docs/2.9.0/native-installation/index.html b/docs/2.9.0/native-installation/index.html index 5d440610ef..6be87de15b 100644 --- a/docs/2.9.0/native-installation/index.html +++ b/docs/2.9.0/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.9.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.9.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.9.0/synchronizing-course-runs/index.html b/docs/2.9.0/synchronizing-course-runs/index.html index 4fd6f775be..ef7e5add15 100644 --- a/docs/2.9.0/synchronizing-course-runs/index.html +++ b/docs/2.9.0/synchronizing-course-runs/index.html @@ -2,10 +2,10 @@ - -Synchronizing course runs between Richie and OpenEdX | Richie - - + +Synchronizing course runs between Richie and OpenEdX | Richie + +
    Version: 2.9.0

    Synchronizing course runs between Richie and OpenEdX

    Richie can receive automatic course runs updates on a dedicated API endpoint.

    @@ -51,6 +51,6 @@

    import hashlib
    import hmac
    import json

    from django.conf import settings

    from microsite_configuration import microsite
    import requests
    from xmodule.modulestore.django import modulestore


    def update_course(course_key, *args, **kwargs):
    """Synchronize an OpenEdX course, identified by its course key, with a Richie instance."""
    course = modulestore().get_course(course_key)
    edxapp_domain = microsite.get_value("site_domain", settings.LMS_BASE)

    data = {
    "resource_link": "https://{:s}/courses/{!s}/info".format(
    edxapp_domain, course_key
    ),
    "start": course.start and course.start.isoformat(),
    "end": course.end and course.end.isoformat(),
    "enrollment_start": course.enrollment_start and course.enrollment_start.isoformat(),
    "enrollment_end": course.enrollment_end and course.enrollment_end.isoformat(),
    "languages": [course.language or settings.LANGUAGE_CODE],
    }

    signature = hmac.new(
    setting.COURSE_HOOK["secret"].encode("utf-8"),
    msg=json.dumps(data).encode("utf-8"),
    digestmod=hashlib.sha256,
    ).hexdigest()

    response = requests.post(
    setting.COURSE_HOOK["url"],
    json=data,
    headers={"Authorization": "SIG-HMAC-SHA256 {:s}".format(signature)},
    )

    Thanks to the signal emitted in OpenEdX, this function can then be triggered each time a course is modified and published:

    -
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    +
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    \ No newline at end of file diff --git a/docs/2.9.0/tls-connection/index.html b/docs/2.9.0/tls-connection/index.html index a8ebf4ceec..e8e841a78b 100644 --- a/docs/2.9.0/tls-connection/index.html +++ b/docs/2.9.0/tls-connection/index.html @@ -2,10 +2,10 @@ - -Connecting Richie and OpenEdX over TLS for development | Richie - - + +Connecting Richie and OpenEdX over TLS for development | Richie + +
    Version: 2.9.0

    Connecting Richie and OpenEdX over TLS for development

    Purpose

    @@ -68,6 +68,6 @@

    $ make run-ssl

    Of course, you can still run apps without ssl by using:

    -
    $ make run
    +
    $ make run
    \ No newline at end of file diff --git a/docs/2.9.0/web-analytics/index.html b/docs/2.9.0/web-analytics/index.html index 9960727883..eea27aad63 100644 --- a/docs/2.9.0/web-analytics/index.html +++ b/docs/2.9.0/web-analytics/index.html @@ -2,13 +2,13 @@ - -Add web analytics to your site | Richie - - + +Add web analytics to your site | Richie + + -
    Version: 2.9.0

    Add web analytics to your site

    The purpose of this file is to document how you can enable a Web Analytics solution. +

    Version: 2.9.0

    Add web analytics to your site

    The purpose of this file is to document how you can enable a Web Analytics solution. Currently Richie only supports by default the Google Analytics using the Google Tag Manager Javascript. But it is possible with little cost to add support for other web analytics solutions.

    Google Analytics

    @@ -53,6 +53,6 @@

    <script type="text/javascript">
    console.log("organization codes: '{{ WEB_ANALYTICS.DIMENSIONS.organizations_codes |join:" | " }}");
    </script>

    +
    <script type="text/javascript">
    console.log("organization codes: '{{ WEB_ANALYTICS.DIMENSIONS.organizations_codes |join:" | " }}");
    </script>
    \ No newline at end of file diff --git a/docs/2.9.1/accessibility-testing/index.html b/docs/2.9.1/accessibility-testing/index.html index 81044939cf..28e35fcbed 100644 --- a/docs/2.9.1/accessibility-testing/index.html +++ b/docs/2.9.1/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.9.1

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.9.1

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems in any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/2.9.1/api/course-run-synchronization-api/index.html b/docs/2.9.1/api/course-run-synchronization-api/index.html index 7e1fcb1c8f..8580b8b85e 100644 --- a/docs/2.9.1/api/course-run-synchronization-api/index.html +++ b/docs/2.9.1/api/course-run-synchronization-api/index.html @@ -2,10 +2,10 @@ - -Course run synchronization API | Richie - - + +Course run synchronization API | Richie + +
    Version: 2.9.1

    Course run synchronization API

    API endpoint allowing remote systems to synchronize their course runs with a Richie instance.

    @@ -52,6 +52,6 @@

    +
    \ No newline at end of file diff --git a/docs/2.9.1/building-the-frontend/index.html b/docs/2.9.1/building-the-frontend/index.html index ce77bf4efc..3ae805f238 100644 --- a/docs/2.9.1/building-the-frontend/index.html +++ b/docs/2.9.1/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.9.1

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.9.1

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/2.9.1/contributing-guide/index.html b/docs/2.9.1/contributing-guide/index.html index e5b61820b3..331f6734c0 100644 --- a/docs/2.9.1/contributing-guide/index.html +++ b/docs/2.9.1/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.9.1

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.9.1

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/2.9.1/css-guidelines/index.html b/docs/2.9.1/css-guidelines/index.html index 127bd03a6c..b3a2c776e0 100644 --- a/docs/2.9.1/css-guidelines/index.html +++ b/docs/2.9.1/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.9.1

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.9.1

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/2.9.1/discover/index.html b/docs/2.9.1/discover/index.html index 994c6d5cb2..cbdaf85d8b 100644 --- a/docs/2.9.1/discover/index.html +++ b/docs/2.9.1/discover/index.html @@ -2,13 +2,13 @@ - -Getting started with Richie | Richie - - + +Getting started with Richie | Richie + + -
    Version: 2.9.1

    Getting started with Richie

    If you're looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    +
    Version: 2.9.1

    Getting started with Richie

    If you're looking for a quick preview of Richie, you can take a look and have a tour of Richie on our dedicated demo site.

    Login/password are admin/admin. The database is regularly flushed.

    Architecture

    Richie is a container-native application but can also be installed @@ -55,6 +55,6 @@

    This approach is used for example on https://www.fun-campus.fr or https://catalogue.edulib.org.

    For a seamless user experience, it is possible to connect a Richie instance to an OpenEdX instance (or some other LMS like Moodle at the cost of minor adaptations), in several ways that we explain in -the LMS connection guide.

    +the LMS connection guide.

    \ No newline at end of file diff --git a/docs/2.9.1/displaying-connection-status/index.html b/docs/2.9.1/displaying-connection-status/index.html index e0c152d4b2..07a136cc28 100644 --- a/docs/2.9.1/displaying-connection-status/index.html +++ b/docs/2.9.1/displaying-connection-status/index.html @@ -2,10 +2,10 @@ - -Displaying OpenEdX connection status in Richie | Richie - - + +Displaying OpenEdX connection status in Richie | Richie + + +
    \ No newline at end of file diff --git a/docs/2.9.1/django-react-interop/index.html b/docs/2.9.1/django-react-interop/index.html index 6f50cd9dd6..7ba430d934 100644 --- a/docs/2.9.1/django-react-interop/index.html +++ b/docs/2.9.1/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.9.1

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.9.1

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -64,6 +64,6 @@

    Context
    {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/2.9.1/docker-development/index.html b/docs/2.9.1/docker-development/index.html index 8714058c1b..b41b2f1f64 100644 --- a/docs/2.9.1/docker-development/index.html +++ b/docs/2.9.1/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.9.1

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.9.1

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/2.9.1/frontend-overrides/index.html b/docs/2.9.1/frontend-overrides/index.html index c5ccc6e40b..98758d6293 100644 --- a/docs/2.9.1/frontend-overrides/index.html +++ b/docs/2.9.1/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.9.1

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.9.1

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/2.9.1/internationalization/index.html b/docs/2.9.1/internationalization/index.html index 2cffa17456..0140fee2db 100644 --- a/docs/2.9.1/internationalization/index.html +++ b/docs/2.9.1/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.9.1

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.9.1

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/2.9.1/lms-backends/index.html b/docs/2.9.1/lms-backends/index.html index 7da3293bfe..399e14009a 100644 --- a/docs/2.9.1/lms-backends/index.html +++ b/docs/2.9.1/lms-backends/index.html @@ -2,10 +2,10 @@ - -Configuring LMS Backends | Richie - - + +Configuring LMS Backends | Richie + +
    Version: 2.9.1

    Configuring LMS Backends

    Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless @@ -115,6 +115,6 @@

    Technical

    If you encounter an issue with this documentation or the backends included in Richie, please open an issue on our repository.

    If you need a custom backend, you can submit a PR or -open an issue and we will consider adding it.

    +open an issue and we will consider adding it.

    \ No newline at end of file diff --git a/docs/2.9.1/lms-connection/index.html b/docs/2.9.1/lms-connection/index.html index 2f3ad4c9f9..b15806608d 100644 --- a/docs/2.9.1/lms-connection/index.html +++ b/docs/2.9.1/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with one or more LMS | Richie - - + +Connecting Richie with one or more LMS | Richie + + -
    Version: 2.9.1

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    +
    Version: 2.9.1

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    Richie can be connected to an LMS in several ways, ranging from SSO to a fully integrated seamless experience.

    As of today, each approach has been implemented for OpenEdX but the same could be done for @@ -63,6 +63,6 @@

    Development

    If you want to activate seamless enrollment locally for development, you will need to set up TLS domains for both Richie and OpenEdX. To do this, head over to our -guide on setting-up TLS connections for Richie and OpenEdX.

    +guide on setting-up TLS connections for Richie and OpenEdX.

    \ No newline at end of file diff --git a/docs/2.9.1/native-installation/index.html b/docs/2.9.1/native-installation/index.html index 405c85e5ae..643bef7b54 100644 --- a/docs/2.9.1/native-installation/index.html +++ b/docs/2.9.1/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.9.1

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: 2.9.1

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/2.9.1/synchronizing-course-runs/index.html b/docs/2.9.1/synchronizing-course-runs/index.html index e8a43a5d35..412d472b07 100644 --- a/docs/2.9.1/synchronizing-course-runs/index.html +++ b/docs/2.9.1/synchronizing-course-runs/index.html @@ -2,10 +2,10 @@ - -Synchronizing course runs between Richie and OpenEdX | Richie - - + +Synchronizing course runs between Richie and OpenEdX | Richie + +
    Version: 2.9.1

    Synchronizing course runs between Richie and OpenEdX

    Richie can receive automatic course runs updates on a dedicated API endpoint.

    @@ -51,6 +51,6 @@

    import hashlib
    import hmac
    import json

    from django.conf import settings

    from microsite_configuration import microsite
    import requests
    from xmodule.modulestore.django import modulestore


    def update_course(course_key, *args, **kwargs):
    """Synchronize an OpenEdX course, identified by its course key, with a Richie instance."""
    course = modulestore().get_course(course_key)
    edxapp_domain = microsite.get_value("site_domain", settings.LMS_BASE)

    data = {
    "resource_link": "https://{:s}/courses/{!s}/info".format(
    edxapp_domain, course_key
    ),
    "start": course.start and course.start.isoformat(),
    "end": course.end and course.end.isoformat(),
    "enrollment_start": course.enrollment_start and course.enrollment_start.isoformat(),
    "enrollment_end": course.enrollment_end and course.enrollment_end.isoformat(),
    "languages": [course.language or settings.LANGUAGE_CODE],
    }

    signature = hmac.new(
    setting.COURSE_HOOK["secret"].encode("utf-8"),
    msg=json.dumps(data).encode("utf-8"),
    digestmod=hashlib.sha256,
    ).hexdigest()

    response = requests.post(
    setting.COURSE_HOOK["url"],
    json=data,
    headers={"Authorization": "SIG-HMAC-SHA256 {:s}".format(signature)},
    )

    Thanks to the signal emitted in OpenEdX, this function can then be triggered each time a course is modified and published:

    -
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    +
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    \ No newline at end of file diff --git a/docs/2.9.1/tls-connection/index.html b/docs/2.9.1/tls-connection/index.html index a8dea40521..a33473874a 100644 --- a/docs/2.9.1/tls-connection/index.html +++ b/docs/2.9.1/tls-connection/index.html @@ -2,10 +2,10 @@ - -Connecting Richie and OpenEdX over TLS for development | Richie - - + +Connecting Richie and OpenEdX over TLS for development | Richie + +
    Version: 2.9.1

    Connecting Richie and OpenEdX over TLS for development

    Purpose

    @@ -68,6 +68,6 @@

    $ make run-ssl

    Of course, you can still run apps without ssl by using:

    -
    $ make run
    +
    $ make run
    \ No newline at end of file diff --git a/docs/2.9.1/web-analytics/index.html b/docs/2.9.1/web-analytics/index.html index 115a6bc406..27beec7c89 100644 --- a/docs/2.9.1/web-analytics/index.html +++ b/docs/2.9.1/web-analytics/index.html @@ -2,13 +2,13 @@ - -Add web analytics to your site | Richie - - + +Add web analytics to your site | Richie + + -
    Version: 2.9.1

    Add web analytics to your site

    The purpose of this file is to document how you can enable a Web Analytics solution. +

    Version: 2.9.1

    Add web analytics to your site

    The purpose of this file is to document how you can enable a Web Analytics solution. Currently Richie only supports by default the Google Analytics using the Google Tag Manager Javascript. But it is possible with little cost to add support for other web analytics solutions.

    Google Analytics

    @@ -53,6 +53,6 @@

    <script type="text/javascript">
    console.log("organization codes: '{{ WEB_ANALYTICS.DIMENSIONS.organizations_codes |join:" | " }}");
    </script>

    +
    <script type="text/javascript">
    console.log("organization codes: '{{ WEB_ANALYTICS.DIMENSIONS.organizations_codes |join:" | " }}");
    </script>
    \ No newline at end of file diff --git a/docs/accessibility-testing/index.html b/docs/accessibility-testing/index.html index f4900de326..1c52e865e1 100644 --- a/docs/accessibility-testing/index.html +++ b/docs/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: 2.25.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: 2.25.0

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems on any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/api/course-run-synchronization-api/index.html b/docs/api/course-run-synchronization-api/index.html index be151b8023..1a7419fa08 100644 --- a/docs/api/course-run-synchronization-api/index.html +++ b/docs/api/course-run-synchronization-api/index.html @@ -2,10 +2,10 @@ - -Course run synchronization API | Richie - - + +Course run synchronization API | Richie + +
    Version: 2.25.0

    Course run synchronization API

    API endpoint allowing remote systems to synchronize their course runs with a Richie instance.

    @@ -52,6 +52,6 @@

    +
    \ No newline at end of file diff --git a/docs/building-the-frontend/index.html b/docs/building-the-frontend/index.html index cff93d3d5e..dc22d6a557 100644 --- a/docs/building-the-frontend/index.html +++ b/docs/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: 2.25.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: 2.25.0

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/contributing-guide/index.html b/docs/contributing-guide/index.html index 2dfc54aec6..a9400f259a 100644 --- a/docs/contributing-guide/index.html +++ b/docs/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: 2.25.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: 2.25.0

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/cookiecutter/index.html b/docs/cookiecutter/index.html index 0b24391b08..18327cb5ac 100644 --- a/docs/cookiecutter/index.html +++ b/docs/cookiecutter/index.html @@ -2,13 +2,13 @@ - -Start your own site | Richie - - + +Start your own site | Richie + + -
    Version: 2.25.0

    Start your own site

    We use Cookiecutter to help you +

    Version: 2.25.0

    Start your own site

    We use Cookiecutter to help you set up a production-ready learning portal website based on Richie in seconds.

    Run Cookiecutter

    @@ -73,6 +73,6 @@

    cookiecutter --overwrite-if-exists gh:openfun/richie --directory=cookiecutter

    Help us improve this project

    After starting your project, please submit an issue let us know how it went and -what other features we should add to make it better.

    +what other features we should add to make it better.

    \ No newline at end of file diff --git a/docs/css-guidelines/index.html b/docs/css-guidelines/index.html index 9a5126c20e..47944876e7 100644 --- a/docs/css-guidelines/index.html +++ b/docs/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: 2.25.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: 2.25.0

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/discover/index.html b/docs/discover/index.html index 6b4565b393..2060ca1b3f 100644 --- a/docs/discover/index.html +++ b/docs/discover/index.html @@ -2,13 +2,13 @@ - -Discover Richie | Richie - - + +Discover Richie | Richie + + -
    Version: 2.25.0

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online +

    Version: 2.25.0

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online courses and MOOCs.

    However, if you need to build a complete website with flexible content to aggregate your courses, in several languages and from different sources, you will soon need a CMS.

    @@ -51,6 +51,6 @@

    Start yo
  • override some css rules or rebuild the whole css with your own variables and customizations,
  • add any DjangoCMS plugin or feature,
  • add any Django third-party application.
  • -

    +
    \ No newline at end of file diff --git a/docs/displaying-connection-status/index.html b/docs/displaying-connection-status/index.html index 354ed3cd13..67294cd678 100644 --- a/docs/displaying-connection-status/index.html +++ b/docs/displaying-connection-status/index.html @@ -2,10 +2,10 @@ - -Displaying OpenEdX connection status in Richie | Richie - - + +Displaying OpenEdX connection status in Richie | Richie + + +
    \ No newline at end of file diff --git a/docs/django-react-interop/index.html b/docs/django-react-interop/index.html index e01f3f070d..bb8be4fdaf 100644 --- a/docs/django-react-interop/index.html +++ b/docs/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: 2.25.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: 2.25.0

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -65,6 +65,6 @@

    Context
        {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/docker-development/index.html b/docs/docker-development/index.html index 40ac08fc20..c577ea9c91 100644 --- a/docs/docker-development/index.html +++ b/docs/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: 2.25.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: 2.25.0

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/filters-customization/index.html b/docs/filters-customization/index.html index 3e02999738..49fd8adc0e 100644 --- a/docs/filters-customization/index.html +++ b/docs/filters-customization/index.html @@ -2,13 +2,13 @@ - -Customizing search filters | Richie - - + +Customizing search filters | Richie + + -
    Version: 2.25.0

    Customizing search filters

    You may want to customize the filters on the left side bar of the search page.

    +
    Version: 2.25.0

    Customizing search filters

    You may want to customize the filters on the left side bar of the search page.

    Richie makes it easy to choose which filters you want to display among the existing filters and in which order. You can also configure the existing filters to change their title or the way they behave. Lastly, you can completely override a filter or create your own custom filter @@ -88,6 +88,6 @@

    opening an issue!

    +opening an issue!

    \ No newline at end of file diff --git a/docs/frontend-overrides/index.html b/docs/frontend-overrides/index.html index a3d3ecb586..ec690df494 100644 --- a/docs/frontend-overrides/index.html +++ b/docs/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: 2.25.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: 2.25.0

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/installation/index.html b/docs/installation/index.html index d43f4379af..2392c02eef 100644 --- a/docs/installation/index.html +++ b/docs/installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie for development | Richie - - + +Installing Richie for development | Richie + + -
    Version: 2.25.0

    Installing Richie for development

    Richie is a container-native application but can also be installed +

    +https://www.nau.edu.pt.

    \ No newline at end of file diff --git a/docs/internationalization/index.html b/docs/internationalization/index.html index 350b6d2d66..67fb02aec0 100644 --- a/docs/internationalization/index.html +++ b/docs/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: 2.25.0

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: 2.25.0

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/joanie-connection/index.html b/docs/joanie-connection/index.html index d0f01ff477..f1dc8ed710 100644 --- a/docs/joanie-connection/index.html +++ b/docs/joanie-connection/index.html @@ -2,10 +2,10 @@ - -Joanie Connection | Richie - - + +Joanie Connection | Richie + + +open an issue on our repository.

    \ No newline at end of file diff --git a/docs/lms-backends/index.html b/docs/lms-backends/index.html index 286c09b130..11035535c7 100644 --- a/docs/lms-backends/index.html +++ b/docs/lms-backends/index.html @@ -2,10 +2,10 @@ - -Configuring LMS Backends | Richie - - + +Configuring LMS Backends | Richie + +
    Version: 2.25.0

    Configuring LMS Backends

    Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless @@ -115,6 +115,6 @@

    Technical

    If you encounter an issue with this documentation or the backends included in Richie, please open an issue on our repository.

    If you need a custom backend, you can submit a PR or -open an issue and we will consider adding it.

    +open an issue and we will consider adding it.

    \ No newline at end of file diff --git a/docs/lms-connection/index.html b/docs/lms-connection/index.html index b97a2c8f13..0216dc083e 100644 --- a/docs/lms-connection/index.html +++ b/docs/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with one or more LMS | Richie - - + +Connecting Richie with one or more LMS | Richie + + -
    Version: 2.25.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    +
    Version: 2.25.0

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    Richie can be connected to an LMS in several ways, ranging from SSO to a fully integrated seamless experience.

    As of today, each approach has been implemented for OpenEdX but the same could be done for @@ -63,6 +63,6 @@

    Development

    If you want to activate seamless enrollment locally for development, you will need to set up TLS domains for both Richie and OpenEdX. To do this, head over to our -guide on setting-up TLS connections for Richie and OpenEdX.

    +guide on setting-up TLS connections for Richie and OpenEdX.

    \ No newline at end of file diff --git a/docs/native-installation/index.html b/docs/native-installation/index.html index f23969b1f0..eb39412cf3 100644 --- a/docs/native-installation/index.html +++ b/docs/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: 2.25.0

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/next/accessibility-testing/index.html b/docs/next/accessibility-testing/index.html index b130cf2784..0b2c132344 100644 --- a/docs/next/accessibility-testing/index.html +++ b/docs/next/accessibility-testing/index.html @@ -2,13 +2,13 @@ - -Automated accessibility checks | Richie - - + +Automated accessibility checks | Richie + + -
    Version: Next

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    +
    Version: Next

    Automated accessibility checks

    Richie includes automated accessibility checks built through a Cypress end-to-end testing infrastructure.

    Automated accessibility checks can only surface around 30% of possible problems on any given page. This does not mean they are not useful, but they cannot replace human audits and developer proficiency.

    We use axe to run these checks. You can find more about axe on the axe-core GitHub repository.

    Testing environment setup

    @@ -27,6 +27,6 @@

    Docu
  • List of all possible violations covered by axe
  • Cypress documentation
  • axe and Cypress integration
  • -

    +
    \ No newline at end of file diff --git a/docs/next/api/course-run-synchronization-api/index.html b/docs/next/api/course-run-synchronization-api/index.html index fd1719f586..70a9bd29d6 100644 --- a/docs/next/api/course-run-synchronization-api/index.html +++ b/docs/next/api/course-run-synchronization-api/index.html @@ -2,10 +2,10 @@ - -Course run synchronization API | Richie - - + +Course run synchronization API | Richie + +
    Version: Next

    Course run synchronization API

    API endpoint allowing remote systems to synchronize their course runs with a Richie instance.

    @@ -52,6 +52,6 @@

    +
    \ No newline at end of file diff --git a/docs/next/building-the-frontend/index.html b/docs/next/building-the-frontend/index.html index 738b97b06e..1b47bdd96b 100644 --- a/docs/next/building-the-frontend/index.html +++ b/docs/next/building-the-frontend/index.html @@ -2,13 +2,13 @@ - -Building Richie's frontend in your own project | Richie - - + +Building Richie's frontend in your own project | Richie + + -
    Version: Next

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    +
    Version: Next

    Building Richie's frontend in your own project

    Richie offers plenty of opportunities to customize the way it works and make it suit the needs of your own project. Most of these go through Django settings.

    Part of Richie is a React frontend however. If you want to change how it works in ways that cannot be changed from the Django settings, you will need to build your own frontend.

    Installing richie-education

    If you have not already, you should create a directory for the frontend in your project. We recommend you mirror Richie's file structure so it's easier to keep track of the changes you make.

    @@ -38,6 +38,6 @@

    Building th
    @import "richie-education/scss/main";

    You are now ready to run the CSS build:

    cd src/frontend
    yarn build-sass
    -

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    +

    This gives you one output CSS file that you can put in the static files directory of your project and use to override Richie's style or add your own parts.

    \ No newline at end of file diff --git a/docs/next/contributing-guide/index.html b/docs/next/contributing-guide/index.html index a3643d652a..51a44403c8 100644 --- a/docs/next/contributing-guide/index.html +++ b/docs/next/contributing-guide/index.html @@ -2,13 +2,13 @@ - -Contributing guide | Richie - - + +Contributing guide | Richie + + -
    Version: Next

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    +
    Version: Next

    Contributing guide

    This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

    We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

    Checking your code

    @@ -37,6 +37,6 @@

    Going further< bin/ directory:

    bin
    ├── exec
    ├── pylint
    ├── pytest
    └── run

    More details and tips & tricks can be found in our development with Docker -documentation

    +documentation

    \ No newline at end of file diff --git a/docs/next/cookiecutter/index.html b/docs/next/cookiecutter/index.html index 873ac9d5e0..a1ee2aac41 100644 --- a/docs/next/cookiecutter/index.html +++ b/docs/next/cookiecutter/index.html @@ -2,13 +2,13 @@ - -Start your own site | Richie - - + +Start your own site | Richie + + -
    Version: Next

    Start your own site

    We use Cookiecutter to help you +

    Version: Next

    Start your own site

    We use Cookiecutter to help you set up a production-ready learning portal website based on Richie in seconds.

    Run Cookiecutter

    @@ -73,6 +73,6 @@

    cookiecutter --overwrite-if-exists gh:openfun/richie --directory=cookiecutter

    Help us improve this project

    After starting your project, please submit an issue let us know how it went and -what other features we should add to make it better.

    +what other features we should add to make it better.

    \ No newline at end of file diff --git a/docs/next/css-guidelines/index.html b/docs/next/css-guidelines/index.html index b4a1f1ff3e..c18281b4bc 100644 --- a/docs/next/css-guidelines/index.html +++ b/docs/next/css-guidelines/index.html @@ -2,13 +2,13 @@ - -CSS Guidelines | Richie - - + +CSS Guidelines | Richie + + -
    Version: Next

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    +
    Version: Next

    CSS Guidelines

    The purpose of these CSS guidelines is to make our CSS as easy as possible to maintain, prune and/or modify over time. To that end, they forgo some of the unwanted parts of CSS. They also require the use of a CSS preprocessor (we picked SASS) to be used effortlessly.

    Our approach is two-pronged. First, we put every piece of CSS as close as we can to the place it is used in a template or component. Second, we use strict class naming rules that act as a replacement to CSS selector combinations.

    File structuration

    Rules should be placed where their purpose is most apparent, and where they are easiest to find.

    @@ -35,6 +35,6 @@

    Quick pointer
  • Comment profusely, whenever you think the CSS is getting complex or it would not be easy to understand its intent.
  • Use !important proactively. !important is a very useful tool when used proactively to make a state or a very specific rule on a tightly-scoped selector stronger. It is however to be avoided at all costs as an easy solution to specificity issues, reactively.
  • -

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    +

    (Direct) child selectors can sometimes be useful. Please remember that the key selector to determine performance is the rightmost one. i.e. div > #example is A LOT more efficient than #example > div although it may appear otherwise at first glance. Browsers parse multi part selectors from the right. See CSS Wizardry for more details.

    \ No newline at end of file diff --git a/docs/next/discover/index.html b/docs/next/discover/index.html index b5ed25dd79..7ad942ddc3 100644 --- a/docs/next/discover/index.html +++ b/docs/next/discover/index.html @@ -2,13 +2,13 @@ - -Discover Richie | Richie - - + +Discover Richie | Richie + + -
    Version: Next

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online +

    Version: Next

    Discover Richie

    Learning Management Systems (LMS) are great tools for hosting and playing interactive online courses and MOOCs.

    However, if you need to build a complete website with flexible content to aggregate your courses, in several languages and from different sources, you will soon need a CMS.

    @@ -51,6 +51,6 @@

    Start yo
  • override some css rules or rebuild the whole css with your own variables and customizations,
  • add any DjangoCMS plugin or feature,
  • add any Django third-party application.
  • -

    +
    \ No newline at end of file diff --git a/docs/next/displaying-connection-status/index.html b/docs/next/displaying-connection-status/index.html index c8f6a2ff1d..34006c116c 100644 --- a/docs/next/displaying-connection-status/index.html +++ b/docs/next/displaying-connection-status/index.html @@ -2,10 +2,10 @@ - -Displaying OpenEdX connection status in Richie | Richie - - + +Displaying OpenEdX connection status in Richie | Richie + + +
    \ No newline at end of file diff --git a/docs/next/django-react-interop/index.html b/docs/next/django-react-interop/index.html index 06e5521d8e..b8a7c36c05 100644 --- a/docs/next/django-react-interop/index.html +++ b/docs/next/django-react-interop/index.html @@ -2,13 +2,13 @@ - -Connecting React components with Django | Richie - - + +Connecting React components with Django | Richie + + -
    Version: Next

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    +
    Version: Next

    Connecting React components with Django

    richie is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.

    Rendering components

    We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.

    We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react class and its modified children for this purpose.

    @@ -65,6 +65,6 @@

    Context
        {
    assets: {
    // SVG sprite used throughout Richie
    icons: "/path/to/icons/sprite.svg"
    }
    }

    -

    Note that it might be expanded in further versions of Richie.

    +

    Note that it might be expanded in further versions of Richie.

    \ No newline at end of file diff --git a/docs/next/docker-development/index.html b/docs/next/docker-development/index.html index 0b80e149b2..99052a6c24 100644 --- a/docs/next/docker-development/index.html +++ b/docs/next/docker-development/index.html @@ -2,13 +2,13 @@ - -Developing Richie with Docker | Richie - - + +Developing Richie with Docker | Richie + + -
    Version: Next

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    +
    Version: Next

    Developing Richie with Docker

    Now that you have Richie up and running, you can start working with it.

    Settings

    Settings are defined using Django Configurations for @@ -78,6 +78,6 @@

    $ sudo sysctl -w vm/max_map_count=262144

    This fix will apply to your current session. To make it permanent on your system, edit the /etc/sysctl.conf file and add the following line:

    -
    vm.max_map_count=262144
    +
    vm.max_map_count=262144
    \ No newline at end of file diff --git a/docs/next/filters-customization/index.html b/docs/next/filters-customization/index.html index 0c3fad7d3c..fa4ea015a8 100644 --- a/docs/next/filters-customization/index.html +++ b/docs/next/filters-customization/index.html @@ -2,13 +2,13 @@ - -Customizing search filters | Richie - - + +Customizing search filters | Richie + + -
    Version: Next

    Customizing search filters

    You may want to customize the filters on the left side bar of the search page.

    +
    Version: Next

    Customizing search filters

    You may want to customize the filters on the left side bar of the search page.

    Richie makes it easy to choose which filters you want to display among the existing filters and in which order. You can also configure the existing filters to change their title or the way they behave. Lastly, you can completely override a filter or create your own custom filter @@ -88,6 +88,6 @@

    opening an issue!

    +opening an issue!

    \ No newline at end of file diff --git a/docs/next/frontend-overrides/index.html b/docs/next/frontend-overrides/index.html index fb83fb1370..1905bf1f5e 100644 --- a/docs/next/frontend-overrides/index.html +++ b/docs/next/frontend-overrides/index.html @@ -2,13 +2,13 @@ - -Overriding frontend components | Richie - - + +Overriding frontend components | Richie + + -
    Version: Next

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    +
    Version: Next

    Overriding frontend components

    Once you are able to build the frontend in your project (see previous section), you can override some parts of the frontend with a drop-in replacement you built yourself.

    This enables you to customize Richie to your own needs in the same way you could do it with backend templates by overriding templates or blocks which do not suit your needs.

    Defining your overrides

    Create a json settings files somewhere in your project. You'll use it to declare the overrides for your custom Richie build.

    @@ -49,6 +49,6 @@

    {
    "components.UserLogin.logIn": {
    "description": "Overriden text for the login button.",
    "message": "Authentication"
    },
    }

    Then, for example if you put your overridden translation in i18n/overrides directory, you have to launch the compilation command below:

      node-modules/richie-education/i18n/compile-translations.js ./i18n/overrides/*.json
    -

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    +

    In this way, "Authentication" will be displayed as label for login button instead of "Sign in".

    \ No newline at end of file diff --git a/docs/next/installation/index.html b/docs/next/installation/index.html index 1f2bf142de..998d64701b 100644 --- a/docs/next/installation/index.html +++ b/docs/next/installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie for development | Richie - - + +Installing Richie for development | Richie + + -
    Version: Next

    Installing Richie for development

    Richie is a container-native application but can also be installed +

    +https://www.nau.edu.pt.

    \ No newline at end of file diff --git a/docs/next/internationalization/index.html b/docs/next/internationalization/index.html index d3c792214d..c52c6aee31 100644 --- a/docs/next/internationalization/index.html +++ b/docs/next/internationalization/index.html @@ -2,13 +2,13 @@ - -Internationalization | Richie - - + +Internationalization | Richie + + -
    Version: Next

    Internationalization

    richie has built-in localization and internationalization:

    +
    Version: Next

    Internationalization

    richie has built-in localization and internationalization:

    • On the backend and CMS, i18n is built on the shoulders of Django and DjangoCMS,
    • On the frontend, we use React Intl.
    • @@ -37,6 +37,6 @@

      Add a new release.

      Before asking for a new language, make sure it does not already exist. If your language already exists in another variant (e.g. Brazilian portuguese vs Portugal portuguese), you may consider -contributing on the existing language if your resources to contribute are limited.

    +contributing on the existing language if your resources to contribute are limited.

    \ No newline at end of file diff --git a/docs/next/joanie-connection/index.html b/docs/next/joanie-connection/index.html index 647f000e46..c56640cbf0 100644 --- a/docs/next/joanie-connection/index.html +++ b/docs/next/joanie-connection/index.html @@ -2,10 +2,10 @@ - -Joanie Connection | Richie - - + +Joanie Connection | Richie + +
    Version: Next

    Joanie Connection

    Joanie delivers an API able to manage course @@ -92,6 +92,6 @@

    Lifet its lifetime is 5 minutes by default.

    Technical support

    If you encounter an issue with this documentation, please -open an issue on our repository.

    +open an issue on our repository.

    \ No newline at end of file diff --git a/docs/next/lms-backends/index.html b/docs/next/lms-backends/index.html index 5f997bc5f8..c996fc5fde 100644 --- a/docs/next/lms-backends/index.html +++ b/docs/next/lms-backends/index.html @@ -2,10 +2,10 @@ - -Configuring LMS Backends | Richie - - + +Configuring LMS Backends | Richie + +
    Version: Next

    Configuring LMS Backends

    Richie can be connected to one or more OpenEdX Learning Management Systems (LMS) for a seamless @@ -115,6 +115,6 @@

    Technical

    If you encounter an issue with this documentation or the backends included in Richie, please open an issue on our repository.

    If you need a custom backend, you can submit a PR or -open an issue and we will consider adding it.

    +open an issue and we will consider adding it.

    \ No newline at end of file diff --git a/docs/next/lms-connection/index.html b/docs/next/lms-connection/index.html index cda9b076a5..514ae9d0a4 100644 --- a/docs/next/lms-connection/index.html +++ b/docs/next/lms-connection/index.html @@ -2,13 +2,13 @@ - -Connecting Richie with one or more LMS | Richie - - + +Connecting Richie with one or more LMS | Richie + + -
    Version: Next

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    +
    Version: Next

    Connecting Richie with one or more LMS

    Connecting Richie to an LMS

    Richie can be connected to an LMS in several ways, ranging from SSO to a fully integrated seamless experience.

    As of today, each approach has been implemented for OpenEdX but the same could be done for @@ -63,6 +63,6 @@

    Development

    If you want to activate seamless enrollment locally for development, you will need to set up TLS domains for both Richie and OpenEdX. To do this, head over to our -guide on setting-up TLS connections for Richie and OpenEdX.

    +guide on setting-up TLS connections for Richie and OpenEdX.

    \ No newline at end of file diff --git a/docs/next/native-installation/index.html b/docs/next/native-installation/index.html index 1f691cfc67..47b385a62a 100644 --- a/docs/next/native-installation/index.html +++ b/docs/next/native-installation/index.html @@ -2,13 +2,13 @@ - -Installing Richie on your machine | Richie - - + +Installing Richie on your machine | Richie + + -
    Version: Next

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie +

    Version: Next

    Installing Richie on your machine

    This document aims to list all needed steps to have a working Richie installation on your laptop.

    A better approach is to use Docker as explained in our guide for container-native installation instructions.

    @@ -106,6 +106,6 @@

    Run serverpython sandbox/manage.py test

    You should now be able to start Django and view the site at localhost:8000

    -

    python sandbox/manage.py runserver

    +

    python sandbox/manage.py runserver

    \ No newline at end of file diff --git a/docs/next/synchronizing-course-runs/index.html b/docs/next/synchronizing-course-runs/index.html index 36449d89fa..249eda5aa2 100644 --- a/docs/next/synchronizing-course-runs/index.html +++ b/docs/next/synchronizing-course-runs/index.html @@ -2,10 +2,10 @@ - -Synchronizing course runs between Richie and OpenEdX | Richie - - + +Synchronizing course runs between Richie and OpenEdX | Richie + +
    Version: Next

    Synchronizing course runs between Richie and OpenEdX

    Richie can receive automatic course runs updates on a dedicated API endpoint.

    @@ -51,6 +51,6 @@

    import hashlib
    import hmac
    import json

    from django.conf import settings

    from microsite_configuration import microsite
    import requests
    from xmodule.modulestore.django import modulestore


    def update_course(course_key, *args, **kwargs):
    """Synchronize an OpenEdX course, identified by its course key, with a Richie instance."""
    course = modulestore().get_course(course_key)
    edxapp_domain = microsite.get_value("site_domain", settings.LMS_BASE)

    data = {
    "resource_link": "https://{:s}/courses/{!s}/info".format(
    edxapp_domain, course_key
    ),
    "start": course.start and course.start.isoformat(),
    "end": course.end and course.end.isoformat(),
    "enrollment_start": course.enrollment_start and course.enrollment_start.isoformat(),
    "enrollment_end": course.enrollment_end and course.enrollment_end.isoformat(),
    "languages": [course.language or settings.LANGUAGE_CODE],
    }

    signature = hmac.new(
    setting.COURSE_HOOK["secret"].encode("utf-8"),
    msg=json.dumps(data).encode("utf-8"),
    digestmod=hashlib.sha256,
    ).hexdigest()

    response = requests.post(
    setting.COURSE_HOOK["url"],
    json=data,
    headers={"Authorization": "SIG-HMAC-SHA256 {:s}".format(signature)},
    )

    Thanks to the signal emitted in OpenEdX, this function can then be triggered each time a course is modified and published:

    -
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    +
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    \ No newline at end of file diff --git a/docs/next/tls-connection/index.html b/docs/next/tls-connection/index.html index 1ba619babd..f8fbec7be6 100644 --- a/docs/next/tls-connection/index.html +++ b/docs/next/tls-connection/index.html @@ -2,10 +2,10 @@ - -Connecting Richie and OpenEdX over TLS for development | Richie - - + +Connecting Richie and OpenEdX over TLS for development | Richie + + +
    $ make run
    \ No newline at end of file diff --git a/docs/next/web-analytics/index.html b/docs/next/web-analytics/index.html index 2ecf936ced..0937bd0fa3 100644 --- a/docs/next/web-analytics/index.html +++ b/docs/next/web-analytics/index.html @@ -2,13 +2,13 @@ - -Add web analytics to your site | Richie - - + +Add web analytics to your site | Richie + + -
    Version: Next

    Add web analytics to your site

    Richie has native support to Google Universal Analytics and Google Tag Manager Web Analytics solutions. +

    Version: Next

    Add web analytics to your site

    Richie has native support to Google Universal Analytics and Google Tag Manager Web Analytics solutions. The purpose of this file is to explain how you can enable one of the supported Web Analytics providers and how you can extend Richie with an alternative solution.

    Google Universal Analytics

    @@ -78,6 +78,6 @@

    +of src/frontend/js/utils/api/web-analytics/google_universal_analytics.ts and change the src/frontend/js/utils/api/web-analytics/index.ts file to include that newer provider.

    \ No newline at end of file diff --git a/docs/synchronizing-course-runs/index.html b/docs/synchronizing-course-runs/index.html index 93e25c5099..4800f900b9 100644 --- a/docs/synchronizing-course-runs/index.html +++ b/docs/synchronizing-course-runs/index.html @@ -2,10 +2,10 @@ - -Synchronizing course runs between Richie and OpenEdX | Richie - - + +Synchronizing course runs between Richie and OpenEdX | Richie + +
    Version: 2.25.0

    Synchronizing course runs between Richie and OpenEdX

    Richie can receive automatic course runs updates on a dedicated API endpoint.

    @@ -51,6 +51,6 @@

    import hashlib
    import hmac
    import json

    from django.conf import settings

    from microsite_configuration import microsite
    import requests
    from xmodule.modulestore.django import modulestore


    def update_course(course_key, *args, **kwargs):
    """Synchronize an OpenEdX course, identified by its course key, with a Richie instance."""
    course = modulestore().get_course(course_key)
    edxapp_domain = microsite.get_value("site_domain", settings.LMS_BASE)

    data = {
    "resource_link": "https://{:s}/courses/{!s}/info".format(
    edxapp_domain, course_key
    ),
    "start": course.start and course.start.isoformat(),
    "end": course.end and course.end.isoformat(),
    "enrollment_start": course.enrollment_start and course.enrollment_start.isoformat(),
    "enrollment_end": course.enrollment_end and course.enrollment_end.isoformat(),
    "languages": [course.language or settings.LANGUAGE_CODE],
    }

    signature = hmac.new(
    setting.COURSE_HOOK["secret"].encode("utf-8"),
    msg=json.dumps(data).encode("utf-8"),
    digestmod=hashlib.sha256,
    ).hexdigest()

    response = requests.post(
    setting.COURSE_HOOK["url"],
    json=data,
    headers={"Authorization": "SIG-HMAC-SHA256 {:s}".format(signature)},
    )

    Thanks to the signal emitted in OpenEdX, this function can then be triggered each time a course is modified and published:

    -
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    +
    from django.dispatch import receiver
    from xmodule.modulestore.django import SignalHandler


    @receiver(SignalHandler.course_published, dispatch_uid='update_course_on_publish')
    def update_course_on_publish(sender, course_key, **kwargs):
    update_course(course_key)
    \ No newline at end of file diff --git a/docs/tls-connection/index.html b/docs/tls-connection/index.html index 8d9f211035..2a06ec3282 100644 --- a/docs/tls-connection/index.html +++ b/docs/tls-connection/index.html @@ -2,10 +2,10 @@ - -Connecting Richie and OpenEdX over TLS for development | Richie - - + +Connecting Richie and OpenEdX over TLS for development | Richie + + +
    $ make run
    \ No newline at end of file diff --git a/docs/web-analytics/index.html b/docs/web-analytics/index.html index 93f48744d9..28b1b34c1d 100644 --- a/docs/web-analytics/index.html +++ b/docs/web-analytics/index.html @@ -2,13 +2,13 @@ - -Add web analytics to your site | Richie - - + +Add web analytics to your site | Richie + + -
    Version: 2.25.0

    Add web analytics to your site

    Richie has native support to Google Universal Analytics and Google Tag Manager Web Analytics solutions. +

    +of src/frontend/js/utils/api/web-analytics/google_universal_analytics.ts and change the src/frontend/js/utils/api/web-analytics/index.ts file to include that newer provider.

    \ No newline at end of file diff --git a/help/index.html b/help/index.html index d3b6753504..ae46fcf525 100644 --- a/help/index.html +++ b/help/index.html @@ -2,10 +2,10 @@ - -Richie - - + +Richie + +

    Need help?

    If your questions are not answered in the docs and various readmes, reach out to us through Github Issues or by email at fun.dev@fun-mooc.fr.

    We also have a regular video-chat meetup with the stakeholders of Richie, (some) Thursdays in the afternoon, UTC time. Reach out to us to know when the next one takes place and come introduce yourself!

    Browse Docs

    Learn more in the documentation. Please tell us if anything is missing or out-of-date.

    Stay up to date

    Keep up with the latest updates on Richie by reading the changelog.

    Join the community

    This project is maintained by a dedicated group of people led by the team at France Université Numérique.

    diff --git a/index.html b/index.html index d4248e3872..ffdd1b0319 100644 --- a/index.html +++ b/index.html @@ -2,10 +2,10 @@ - -Richie - - + +Richie + +

    Richie helps educators create rich online learning portals

    A CMS for Open Education

    Richie helps educators create online learning portals.

    Build websites including online course catalogs in days with Richie's content management system.

    Get started

    Multilingual by Design

    From the ground up, Richie is localized and handles multilingual content.

    Built for Search

    Richie integrates a powerful course search engine with autosuggestion and advanced filtering options.

    Fully Customizable

    Personalize course catalogs by swapping colors and styles, or dive deep to customize the built-in search engine.

    Fully Open Source

    Built with Django CMS, Django, and React - everything is in the open. Richie is available under the MIT license.

    Users can modify and distribute documentation freely. Start contributing today.

    View code

    What Richie brings you

    An LMS-agnostic Education Portal

    Course catalogs can synchronize with one or more LMS instances running different software, such as Open edX or Moodle. Richie aggregates it all for your users.

    Author-first

    Content authors do not have to rely on software engineers to create and update all materials in Richie. Instead, authors use a rich editor interface to maintain content.

    Advanced Access Rights and Moderation

    Everything is managed through comprehensive access rights from CMS content structured objects like organizations, courses, and categories. Rights scale from individual users to enterprise-wide.

    A Multilingual Website

    Richie is available in more than one language, and you can add yours by talking to us. All the content can be added and managed in as many languages as you need. Richie is available in English, French, Spanish, and more. Want to add yours? Reach out! Richie supports content creation and management in as many languages as you need.

    An Extensible Platform

    Richie is a Django application with a NPM package. You can install it as a third-party app to build learning platforms.

    Join the Community

    Project stakeholders regularly check in through virtual meetups in English. Discussions take place in the #richie channel of the DjangoCMS Slack instance

    We encourage potential and new contributors to introduce themselves and get help.

    Who is Using Richie?

    France Université NumériqueNAUEDUlib
    View demo
    diff --git a/users/index.html b/users/index.html index b86bccb3cb..4c1f9078e0 100644 --- a/users/index.html +++ b/users/index.html @@ -2,10 +2,10 @@ - -Richie - - + +Richie + + diff --git a/versions/index.html b/versions/index.html index cbe0e4756a..33390e18d2 100644 --- a/versions/index.html +++ b/versions/index.html @@ -2,10 +2,10 @@ - -Richie - - + +Richie + +

    Richie versions and documentation

    New versions of this project are shipped regularly. Every new version includes its own version of the documentation.

    Versions below 1.12.0 did not have a dedicated documentation website.

    Current version (Stable)

    2.25.0DocumentationRelease Notes

    Pre-release versions

    masterDocumentationSource Code

    Past Versions

    Here you can find previous versions of the documentation.

    2.25.0-beta.1DocumentationRelease Notes
    2.25.0-beta.0DocumentationRelease Notes
    2.24.1DocumentationRelease Notes
    2.24.0DocumentationRelease Notes
    2.23.0DocumentationRelease Notes
    2.22.0DocumentationRelease Notes
    2.21.1DocumentationRelease Notes
    2.21.0DocumentationRelease Notes
    2.20.1DocumentationRelease Notes
    2.20.0DocumentationRelease Notes
    2.19.0DocumentationRelease Notes
    2.18.0DocumentationRelease Notes
    2.17.0DocumentationRelease Notes
    2.16.0DocumentationRelease Notes
    2.15.1DocumentationRelease Notes
    2.15.0DocumentationRelease Notes
    2.14.1DocumentationRelease Notes
    2.14.0DocumentationRelease Notes
    2.13.0DocumentationRelease Notes
    2.12.0DocumentationRelease Notes
    2.11.0DocumentationRelease Notes
    2.10.0DocumentationRelease Notes
    2.9.1DocumentationRelease Notes
    2.9.0DocumentationRelease Notes
    2.8.2DocumentationRelease Notes
    2.8.1DocumentationRelease Notes
    2.8.0DocumentationRelease Notes
    2.7.1DocumentationRelease Notes
    2.7.0DocumentationRelease Notes
    2.6.0DocumentationRelease Notes
    2.5.0DocumentationRelease Notes
    2.4.0DocumentationRelease Notes
    2.3.3DocumentationRelease Notes
    2.3.2DocumentationRelease Notes
    2.3.1DocumentationRelease Notes
    2.3.0DocumentationRelease Notes
    2.2.0DocumentationRelease Notes
    2.1.0DocumentationRelease Notes
    2.0.1DocumentationRelease Notes
    2.0.0DocumentationRelease Notes
    1.17DocumentationRelease Notes
    1.16DocumentationRelease Notes
    1.15DocumentationRelease Notes
    1.14DocumentationRelease Notes
    1.13DocumentationRelease Notes
    1.12DocumentationRelease Notes

    You can find past versions of this project on GitHub.