Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • documentation/docs/dev
  • totten/dev
  • bgm/dev
  • ivan_compucorp/dev
  • seamuslee/dev
  • artfulrobot/dev
  • ufundo/dev
  • wmortada/dev
  • lucky091588/dev
  • DaveD/dev
  • jtwyman/dev
  • rukkykofi/dev
  • JonGold/dev
  • jaapjansma/developer-docs
  • alainb/dev
  • noah/dev
  • justinfreeman/dev
  • pradeep/dev
  • larssg/dev
  • eileen/dev
  • darrick/dev
  • mattwire/dev
  • colemanw/dev
  • homotechsual/dev
  • JoeMurray/dev
  • maynardsmith/dev
  • kurund/dev
  • rocxa/dev
  • AllenShaw/dev
  • bradleyt/dev
  • chrisgaraffa/dev
  • martin.w/dev
  • herbdool/dev
  • MattTrim1/dev
  • Detlev/dev
  • ErikHommel/dev
  • brienne/devdocs
  • pminf/dev
  • SarahFG/dev
  • ayduns/dev
  • JKingsnorth/dev
  • ginkgomzd/dev
  • nicol/dev
  • almeidam/dev
  • arthurm/dev
  • damilare/dev
  • semseysandor/dev
  • major/devdocs
  • usha.makoa/dev
  • yurg/dev
  • shaneonabike/dev
  • andie/dev
  • mmyriam/dev
  • gngn/dev
  • florian-dieckmann/dev
  • jade/dev
  • luke.stewart/dev
  • vinaygawade/dev
58 results
Show changes
Showing
with 362 additions and 553 deletions
docs/img/gitlab-reference.png

2.93 KiB

This folder contains images for the CiviCRM demo documentation.
docs/img/money_settings.png

87.8 KiB

docs/img/mysql_workbench_civicrm_country_foreign_keys.png

23.8 KiB

docs/img/mysql_workbench_civicrm_country_tables.png

52.1 KiB

docs/img/permission-admin.png

158 KiB

docs/img/quickform-lifecycle.png

59.6 KiB

docs/img/repository-access.png

127 KiB

docs/img/searchkit/apiexport.png

41.9 KiB

docs/img/searchkit/exportsearch.png

53.5 KiB

docs/img/searchkit/managed.png

96.2 KiB

docs/img/searchkit/prefilled.png

22.3 KiB

docs/img/searchkit/searchkit-formbuilder-schema.png

32.8 KiB

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="553.56763"
height="289.14532"
viewBox="0 0 553.56762 289.14532"
version="1.1"
id="svg8"
inkscape:version="0.92.1 unknown"
sodipodi:docname="security-inputs-and-outputs.svg">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="200.97324"
inkscape:cy="221.03966"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
units="px"
inkscape:window-width="1548"
inkscape:window-height="868"
inkscape:window-x="52"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:snap-global="false"
fit-margin-top="10"
fit-margin-left="10"
fit-margin-right="10"
fit-margin-bottom="10" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-3.8845495,-259.39822)">
<path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 156.48242,160.63672 v 11.36914 H 59 v 34.60742 h 97.48242 v 11.3711 l 32.16602,-28.67383 z"
transform="translate(3.8845495,257.36697)"
id="rect4697"
inkscape:connector-curvature="0" />
<path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="M 156.48242,39.822266 V 51.193359 H 10 v 34.607422 h 146.48242 v 11.369141 l 32.16602,-28.673828 z"
transform="translate(3.8845495,257.36697)"
id="rect4743"
inkscape:connector-curvature="0" />
<path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 156.48242,100.22852 v 11.37109 H 29 v 34.60742 h 127.48242 v 11.37109 l 32.16602,-28.67382 z"
transform="translate(3.8845495,257.36697)"
id="rect4703"
inkscape:connector-curvature="0" />
<path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 156.48242,221.04297 v 11.37109 H 105 v 34.60742 h 51.48242 v 11.3711 l 32.16602,-28.67578 z"
transform="translate(3.8845495,257.36697)"
id="rect4691"
inkscape:connector-curvature="0" />
<rect
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="rect4485"
width="106.07417"
height="238.40738"
x="206.96291"
y="298.63617"
rx="3.6358359" />
<text
xml:space="preserve"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:18.66666603px;line-height:25px;font-family:Quicksand;-inkscape-font-specification:'Quicksand Medium';font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
x="259.91797"
y="413.01395"
id="text4489"><tspan
sodipodi:role="line"
id="tspan4487"
x="259.91797"
y="413.01395"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:21.33333397px;font-family:Roboto;-inkscape-font-specification:Roboto;text-align:center;text-anchor:middle">CiviCRM</tspan><tspan
sodipodi:role="line"
x="259.91797"
y="438.69705"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:21.33333397px;font-family:Roboto;-inkscape-font-specification:Roboto;text-align:center;text-anchor:middle"
id="tspan4485">codebase</tspan></text>
<text
xml:space="preserve"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:18.66666603px;line-height:25px;font-family:Quicksand;-inkscape-font-specification:'Quicksand Medium';font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
x="99.383942"
y="283.61697"
id="text4498"><tspan
sodipodi:role="line"
x="99.383949"
y="283.61697"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.66666603px;font-family:Roboto;-inkscape-font-specification:Roboto;text-align:center;text-anchor:middle"
id="tspan4496">Untrusted inputs</tspan></text>
<text
id="text4492"
y="283.61697"
x="419.67853"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.66666603px;line-height:25px;font-family:Roboto;-inkscape-font-specification:Roboto;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:center;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:middle;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
xml:space="preserve"><tspan
id="tspan4490"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.66666603px;line-height:25px;font-family:Roboto;-inkscape-font-specification:Roboto;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:center;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:middle;white-space:normal;shape-padding:0;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:stroke fill markers"
y="283.61697"
x="419.67853"
sodipodi:role="line">Sensitive outputs</tspan></text>
<text
xml:space="preserve"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:25px;font-family:Roboto;-inkscape-font-specification:Roboto;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:center;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:middle;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
x="120.83499"
y="453.31287"
id="text4610"><tspan
sodipodi:role="line"
x="120.83499"
y="453.31287"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:25px;font-family:Roboto;-inkscape-font-specification:Roboto;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:center;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:middle;white-space:normal;shape-padding:0;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:stroke fill markers"
id="tspan4608">Form data</tspan></text>
<text
xml:space="preserve"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:16px;line-height:25px;font-family:Quicksand;-inkscape-font-specification:'Quicksand Medium';font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
x="99.397491"
y="332.49866"
id="text4514"><tspan
sodipodi:role="line"
x="99.397491"
y="332.49866"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:Roboto;-inkscape-font-specification:Roboto;text-align:center;text-anchor:middle"
id="tspan4512">URL parameters</tspan></text>
<text
id="text4504"
y="392.90576"
x="107.56155"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:25px;font-family:Roboto;-inkscape-font-specification:Roboto;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:center;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:middle;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
xml:space="preserve"><tspan
id="tspan4502"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:25px;font-family:Roboto;-inkscape-font-specification:Roboto;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:center;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:middle;white-space:normal;shape-padding:0;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:stroke fill markers"
y="392.90576"
x="107.56155"
sodipodi:role="line">URL fragment</tspan></text>
<text
xml:space="preserve"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:25px;font-family:Roboto;-inkscape-font-specification:Roboto;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:center;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:middle;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
x="140.7178"
y="513.72003"
id="text4616"><tspan
sodipodi:role="line"
x="140.7178"
y="513.72003"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:25px;font-family:Roboto;-inkscape-font-specification:Roboto;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:center;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:middle;white-space:normal;shape-padding:0;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:stroke fill markers"
id="tspan4614">etc...</tspan></text>
<path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 469.81618,297.18924 v 11.37109 H 333.88455 v 34.60742 h 135.93163 v 11.36914 l 32.16601,-28.67383 z"
id="rect4749"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" />
<text
id="text4534"
y="332.49863"
x="403.89871"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:25px;font-family:Roboto;-inkscape-font-specification:Roboto;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:center;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:middle;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
xml:space="preserve"><tspan
id="tspan4532"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:25px;font-family:Roboto;-inkscape-font-specification:Roboto;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:center;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:middle;white-space:normal;shape-padding:0;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:stroke fill markers"
y="332.49863"
x="403.89871"
sodipodi:role="line">MySQL database</tspan></text>
<path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 503.5951,357.59549 v 11.37109 H 333.88455 V 403.574 H 503.5951 v 11.37109 l 32.16602,-28.67382 z"
id="rect4755"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" />
<path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 515.28613,418.00369 v 11.37109 H 333.88455 v 34.60547 h 181.40158 v 11.3711 l 32.16602,-28.67383 z"
id="rect4761"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" />
<path
inkscape:connector-curvature="0"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 385.36697,478.40994 v 11.37109 h -51.48242 v 34.60742 h 51.48242 v 11.3711 l 32.16602,-28.67578 z"
id="rect4679" />
<text
id="text4518"
y="513.72003"
x="365.7178"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:25px;font-family:Roboto;-inkscape-font-specification:Roboto;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:center;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:middle;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
xml:space="preserve"><tspan
id="tspan4516"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:25px;font-family:Roboto;-inkscape-font-specification:Roboto;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:center;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:middle;white-space:normal;shape-padding:0;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:stroke fill markers"
y="513.72003"
x="365.7178"
sodipodi:role="line">etc...</tspan></text>
<text
xml:space="preserve"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:25px;font-family:Roboto;-inkscape-font-specification:Roboto;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:center;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:middle;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
x="420.83621"
y="392.07123"
id="text4802"><tspan
sodipodi:role="line"
id="tspan4800"
x="420.83621"
y="392.07123">Privileged user's DOM</tspan></text>
<text
xml:space="preserve"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:25px;font-family:Roboto;-inkscape-font-specification:Roboto;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:center;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:middle;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
x="427.66547"
y="452.68924"
id="text4806"><tspan
sodipodi:role="line"
id="tspan4804"
x="427.66547"
y="452.68924">Server shell commands</tspan></text>
</g>
</svg>
# CiviCRM Developer Guide
!!! warning "Notice"
This guide is not yet complete.
As of early 2017 we are actively working to migrate content in from the
[wiki]. Read more about this [migration process][migration], including how
to help out!
[CiviCRM](https://civicrm.org) is an open-source application. The code can be poked, prodded, twisted, and hacked. It can be customized, extended, and collaboratively developed. This documentation tells you how to do that.
[wiki]: http://wiki.civicrm.org/confluence/display/CRMDOC/Develop
[migration]: https://wiki.civicrm.org/confluence/display/CRMDOC/Content+migration+from+wiki+to+Developer+Guide
It starts with a high level introduction to get you familiar with CiviCRM development. It covers setting up your development environment, checking whether or not you actually need to implement your own custom code (i.e. you can't achieve what you want through configuration or installing an already existing extension), best practice ways to extend CiviCRM (a.k.a. how to write an extension), things you should know before you start hacking on core, and best practice for testing.
The guide also includes detailed references for tools and subsystems of CiviCRM. These cover topics like the API and hook system and are intended for use by people that are familiar with CiviCRM development.
[CiviCRM](https://civicrm.org) is an open-source application. The code can be
poked, prodded, twisted, and hacked. It can be customized, extended, and
collaboratively developed. This documentation tells you how to do that.
## Editing this guide
It starts with a high level introduction to get you familiar
with CiviCRM development. It covers setting up your development environment,
checking whether or not you actually need to implement your own custom code (i.e. you can't achieve what you
want through configuration or installing an already existing extension), best
practice ways to extend CiviCRM (a.k.a. how to write an extension), things you
should know before you start hacking on core, and best practice for testing.
The guide also includes detailed references for tools and subsystems
of CiviCRM. These cover topics like the API and hook system and are intended
for use by people that are familiar with CiviCRM development.
## Editing & reading offline
- This documentation is made with mkdocs and
[stored in GitHub](https://github.com/civicrm/civicrm-dev-docs)
- See the "[Writing Documentation](documentation.md)" section in this guide
for specific details on editing this documentation (and others using
mkdocs). You can also learn how to read these docs off-line!
* This guide is made with MkDocs and stored in a [git repository](https://lab.civicrm.org/documentation/docs/dev).
* See the "[Writing Documentation](documentation/index.md)" section in this guide for specific details on editing this guide.
## Credits
This guide is collaboratively written by the CiviCRM community, with facilitation from the [Documentation Working Group](https://civicrm.org/working-groups/documentation).
$(function() {
// Automatically scroll the navigation menu to the active element
// https://github.com/civicrm/civicrm-dev-docs/issues/21
$.fn.isFullyWithinViewport = function(){
var viewport = {};
viewport.top = $(window).scrollTop();
viewport.bottom = viewport.top + $(window).height();
var bounds = {};
bounds.top = this.offset().top;
bounds.bottom = bounds.top + this.outerHeight();
return ( ! (
(bounds.top <= viewport.top) ||
(bounds.bottom >= viewport.bottom)
) );
};
if( !$('li.toctree-l1.current').isFullyWithinViewport() ) {
$('.wy-nav-side')
.scrollTop(
$('li.toctree-l1.current').offset().top -
$('.wy-nav-side').offset().top -
60
);
}
});
# Markdown Syntax
Learning [Markdown](https://en.wikipedia.org/wiki/Markdown)
language is useful for:
* Writing CiviCRM [extensions](extend) -- In order for your extension to be
compliant, you must provide extension documentation, written in markdown.
* Writing other *.md* files that display on [GitHub]
* Contributing to CiviCRM [documentation](documentation)
* Chatting on [Mattermost](http://chat.civicrm.org)
* Q&A on [Stack Exchange](http://civicrm.stackexchange.com)
[GitHub]: https://github.com
Markdown language is mostly consistent across these platforms, but some
discrepancies do exist. The `mkdocs` specific guide for markdown, as used in
this book is
[here](http://www.mkdocs.org/user-guide/writing-your-docs).
## CiviCRM markdown code standards {:#standards}
To maintain some consistency and peace of mind for documentation content editors, we've [agreed](https://github.com/civicrm/civicrm-dev-docs/issues/43) to *recommend* the following syntax as markdown code standards. These are not hard rules though.
* **Line length:** write long lines (i.e. one line per paragraph) and set your text editor to view them with a "soft wrap".
* **Ordered lists:** use `1.` as delimiters.
* **Unordered lists:** use `*` to delimiters.
* **Headings:** use hashes like `## Heading 2`.
## Basics
* `*italics*`
* `**bold**`
* `***bold and italic***`
* `~~strikethrough~~` *(GitHub/Mattermost/StackExchange)*
* `<del>strikethrough</del>` *(mkdocs)*
Alternate syntax: Underscores for `_italics_` and `__bold__` also work on most
platforms.
## Hyperlinks
* A basic hyperlink (in a sentence)
Try [CiviCRM](https://civicrm.org) for your database.
* An internal hyperlink on mkdocs. The `.md` is optional.
*Make sure to use an absolute path and precede the path with a slash,
as shown below.*
[extensions](/extensions/basics)
[extensions](/extensions/basics.md)
* With long URLs, the following syntax is better.
See [this issue][CRM-19799] for more details.
[CRM-19799]: https://issues.civicrm.org/jira/browse/CRM-19799
- The second line can be placed anywhere in the file.
- Optionally, if the link ID ("CRM-19799" in this case) is omitted, you
can use the link text ("this issue") to reference the link in the
second line.
## Line breaks and whitespace
**Single line breaks** in markdown code are eliminated in display:
```md
This text will all show up
on the
same
line.
```
This makes it easy to avoid very long lines in markdown code. As a rule of
thumb, keep your markdown code free of lines longer than 80 characters
where possible.
**Double line breaks** create separate paragraphs:
```md
This is
one paragraph.
This is a second.
```
## Headings
```md
# Heading 1
## Heading 2
### Heading 3
#### Heading 4
```
The above syntax is [called](http://pandoc.org/MANUAL.html#headers)
"ATX style headers" in markdown terminology, and is the [preferred](#standards)
syntax within the CiviCRM community.
An alternate syntax called "setext style headers" works for h1 and h2 as
follows (but please avoid creating new content with this syntax).
```md
Heading 1
=========
Heading 2
---------
```
### Heading IDs
Heading IDs allow you to link to specific sections in a page by appending
the heading ID to the page URL. Most markdown platforms (e.g. MkDocs, GitHub)
automatically set a heading ID for every heading and do so using the text of
the heading itself. Sticking with the default is great is most cases, however
sometimes you want to override it. Some markdown platforms (e.g. MkDocs)
allow you to set *custom* heading IDs to override the automatically chosen
value.
Setting a custom ID:
```md
## How to foo a bar {:#foo}
```
This is helpful when you think that readers are likely to frequently link
to this section in the future.
* Custom heading IDs will remain the same (thus preserving incoming links) even
after the text of the heading is edited.
* Custom heading IDs create shorter URLs.
Custom heading IDs only work in MkDocs when the following code is used to enable
the [Attribute Lists](https://pythonhosted.org/Markdown/extensions/attr_list.html)
extension:
```yml
markdown_extensions:
- markdown.extensions.attr_list
```
## Lists
### Unordered lists
```md
* My first item is here.
* My second item is here and a
bit longer than the first.
* Then, a third.
```
Alternate syntax:
* Unordered lists also recognize `-` and `+` as item delimiters.
* Markdown is somewhat flexible with the quantity and position of spaces when
making lists, but using 3 spaces after the dash means that sub-lists look
nicer in code.
### Ordered lists
```md
1. Item
1. Item
1. Item
```
Alternate syntax:
* Ordered lists items are automatically re-numbered sequentially upon display
which means all items can begin with `1`, or they can be ordered
sequentially in code.
### Nested lists
List items must be indented 4 spaces:
```md
1. Item
1. Item
1. Item
1. Item
* Item
* Item
* Item
1. Item
```
## Code
### Inline code
Use backticks to create inline monospace text:
```md
Some `monospace text` amid a paragraph.
```
And if you need to put a backtick inside your monospace text, begin and end
with two backticks:
```md
Some ``monospace text with `backticks` inside``, and all amid a paragraph.
```
### Code blocks
A block of **"fenced code"** with three or more backticks on their own line.
````md
```
CODE
BLOCK
```
````
*Fenced code can use more backticks when necessary to represent code with
3 backticks (which is what you'd see in the source for this page).*
Alternate syntax: For fenced code, the tilde `~` character also works
in place of the backtick character but should be avoided for consistency.
A block of **"indented code"** with four spaces at the start of each line:
```md
CODE
BLOCK
```
### Syntax highlighting for code
* For code blocks, most platforms (e.g. mkdocs, GitHub) will guess guess the
language of the code and automatically apply syntax highlighting to the
display.
* To force a particular type of syntax highlighting, use fenced code with a
keyword (like `javascript` in this case) as follows:
```javascript
var cj = CRM.$ = jQuery;
```
* Available language keywords for forced syntax highlighting differ slightly
by markdown platform, but here are some common ones:
`as`, `atom`, `bas`, `bash`, `boot`, `c`, `c++`, `cake`, `cc`, `cjsx`,
`cl2`, `clj`, `cljc`, `cljs`, `cljsc`, `cljs.hl`, `cljx`, `clojure`,
`coffee`, `_coffee`, `coffeescript`, `cpp`, `cs`, `csharp`, `cson`, `css`,
`d`, `dart`, `delphi`, `dfm`, `di`, `diff`, `django`, `docker`,
`dockerfile`, `dpr`, `erl`, `erlang`, `f90`, `f95`, `freepascal`, `fs`,
`fsharp`, `gcode`, `gemspec`, `go`, `groovy`, `gyp`, `h`, `h++`,
`handlebars`, `haskell`, `haxe`, `hbs`, `hic`, `hpp`, `hs`, `html`,
`html.handlebars`, `html.hbs`, `hx`, `iced`, `irb`, `java`, `javascript`,
`jinja`, `jl`, `js`, `json`, `jsp`, `jsx`, `julia`, `kotlin`, `kt`, `ktm`,
`kts`, `lazarus`, `less`, `lfm`, `lisp`, `lpr`, `lua`, `m`, `mak`,
`makefile`, `markdown`, `matlab`, `md`, `mk`, `mkd`, `mkdown`, `ml`, `mm`,
`nc`, `objc`, `obj-c`, `objectivec`, `ocaml`, `osascript`, `pas`, `pascal`,
`perl`, `php`, `pl`, `plist`, `podspec`, `powershell`, `pp`, `ps`, `ps1`,
`puppet`, `py`, `python`, `r`, `rb`, `rs`, `rss`, `ruby`, `rust`, `scala`,
`scheme`, `scm`, `scpt`, `scss`, `sh`, `sld`, `smalltalk`, `sql`, `st`,
`swift`, `tex`, `thor`, `v`, `vb`, `vbnet`, `vbs`, `vbscript`, `veo`,
`xhtml`, `xml`, `xsl`, `yaml`, `zsh`
* Syntax highlighting cannot be forced for indented code.
* Syntax highlighting is not available for inline code.
* [Stack Exchange syntax highlighting][stack exchange syntax highlighting] is
done differently.
[stack exchange syntax highlighting]: http://stackoverflow.com/editing-help#syntax-highlighting
### Code blocks within lists
You can use **indented code within lists** by keeping a blank line
above/below and indenting *4 spaces more than your list content*, like this:
```md
* First item
* Look at this code:
CODE BLOCK WITHIN
TOP LEVEL LIST ITEM
* More list items
* A nested list is here:
1. Alpha
1. Beta, with some code
CODE BLOCK WITHIN
SUB-LIST ITEM
1. Gamma
* Fun, right?
```
**Fenced code within lists** is shown below. It works on GitHub but **not
mkdocs**:
````md
* First item
* Look at this code:
```md
code
block
```
* More list items
````
## Admonitions
### Types
!!! note
I am a "note" admonition.
!!! tip
I am a "tip" admonition.
!!! warning
I am a "warning" admonition.
!!! danger
I am a "danger" admonition.
Other types
* "hint", "important" (visually identical to "tip")
* "attention", "caution" (visually identical to "warning")
* "error" (visually identical to "danger")
### Syntax
Simple example:
```md
!!! note
This feature is only available as of CiviCRM 4.5.
```
Add a custom title (make sure to quote the title):
```md
!!! danger "Don't try this at home!"
Stand back. I'm about to try science!
```
### Enabling
Admonitions only work in MkDocs when the following code is used to enable
the [Admonition extension](https://pythonhosted.org/Markdown/extensions/admonition.html):
```yml
markdown_extensions:
- markdown.extensions.admonition
```
## Images
Images function mostly the same as hyperlinks, but preceded by an exclamation
point and with alt text in place of the link text.
```md
![Alt text](image.png)
```
or
```md
![Alt text][id]
[id]: image.png
```
## Other markdown syntax
* [Tables] (to be avoided when possible)
* [Emojis] (great for Mattermost)
* Blockquotes
> This text is a blockquote, typically used
> to represent prose written by a person. It
> will be displayed slightly indented.
[Emojis]: http://www.webpagefx.com/tools/emoji-cheat-sheet/
[Tables]: https://help.github.com/articles/organizing-information-with-tables
## External references
* [Mattermost markdown](https://docs.mattermost.com/help/messaging/formatting-text.html)
* [Stack Exchange markdown](http://stackoverflow.com/editing-help)
* [GitHub markdown](https://help.github.com/categories/writing-on-github/)
* [Official markdown reference](https://daringfireball.net/projects/markdown/syntax)
(though somewhat difficult to read)
# Development requirements
## Languages and Services
- Unix-like environment (Linux, OS X, or a virtual machine)
- [PHP v5.3+](http://php.net/)
- [MySQL v5.1+](http://mysql.com/)
- [NodeJS](https://nodejs.org/)
- [Git](https://git-scm.com/)
- Recommended: Apache HTTPD v2.2+
- Recommended: Ruby/Rake
## Command Line
There are many ways to install MySQL, PHP, and other dependencies -- for
example, `apt-get` and `yum` can download packages automatically; `php.net`
and `mysql.com` provide standalone installers; and MAMP/XAMPP provide
bundled installers.
Civi development should work with most packages -- but there's one proviso:
***the command-line must support standard commands*** (`php`, `mysql`,
`node`, `git`, `bash`, etc).
Some packages are configured properly out-of-the-box. (Linux distributions
do a pretty good job of this.) Other packages require extra configuration
steps (e.g. [Setup Command Line
PHP](http://wiki.civicrm.org/confluence/display/CRMDOC/Setup+Command-Line+PHP)
for MAMP).
In subsequent steps, the download script will attempt to identify
misconfigurations and display an appropriate message.
## Buildkit
The developer docs reference a large number of developer tools, such as
`drush` (the Drupal command line), `civix` (the CiviCRM code-generator), and
`karma` (the Javascript tester).
Many of these tools are commonly used by web developers, so you may have
already installed a few. You could install all the tools individually --
but that takes a lot of work.
[civicrm-buildkit](https://github.com/civicrm/civicrm-buildkit) provides
a script which downloads the full collection.
### Installing buildkit on Ubuntu
If you have a new installation of Ubuntu 12.04 or 14.04, then you can download
everything -- buildkit and the system requirements (`git`, `php`, `apache`,
`mysql`, etc) -- with one command. This command will install buildkit to
`~/buildkit`:
```bash
curl -Ls https://civicrm.org/get-buildkit.sh | bash -s -- --full --dir ~/buildkit
```
Note:
- When executing the above command, you must ***NOT*** run as `root`.
(Doing so will produce incorrect permissions.) Instead, you must have
`sudo` permissions.
- The `--full` option is opinionated; it specifically installs `php`,
`apache`, and `mysql` (rather than `hvm`, `nginx`, `lighttpd`, or
`percona`). If you try to mix `--full` with alternative systems, then
expect conflicts.
### Installing buildkit on other systems
If you already installed the requirements (`git`, `php`, etc), then you can
download buildkit to `~/buildkit` with these commands:
```bash
git clone https://github.com/civicrm/civicrm-buildkit.git buildkit
cd buildkit/bin
./civi-download-tools
export PATH="$PWD:$PATH"
```
### Upgrading buildkit
If you have previously downloaded buildkit and want to update it, run:
```bash
cd buildkit
git pull
./bin/civi-download-tools
```
# Search Kit Displays
SearchKit Displays are responsible for rendering the results of a SavedSearch query.
Each Display has a "type". Most types (Table, List, Grid) are intended to render as part of a webpage (see Embedding Displays),
but a few types have specialized output such as an [Autocomplete display](../framework/autocomplete.md) which populates a form dropdown-select,
or an Entity display which writes to a SQL table.
## Embedding Displays
Search displays can be embedded in any AngularJS content with their component tag, which requires the name of the SavedSearch,
the name of the Display, the name of the entity and the configuration settings, e.g.
```
<crm-search-display-list search="'MySavedSearch'" display="'MyListDisplay'" api-entity="Contact" settings="{style: 'ul', limit: 50, pager: true, columns: [{key: 'id', dataType: 'Integer', type: 'field'}, {key: 'display_name', dataType: 'String', type: 'field'}]}">
</crm-search-display-list>
```
That's a lot of data to insert into the markup, and it would get out-of-sync with any updates made to the SavedSearch or SearchDisplay
in the database. So Search Kit implements a markup preprocessor to insert the configuration data at runtime. All it needs is the
`search-name` and `display-name` and it will add the rest:
```
<crm-search-display-list search-name="MySavedSearch" display-name="MyListDisplay"></crm-search-display-list>
```
Note: The preprocessor only works on [Afforms](../afform/search-forms.md).
## Creating a New Display Type
An extension can add new display types in addition to the ones included with Search Kit (Table, List, etc).
1. Add the name of the new display type to the `search_display_type` option list. [`hook_civicrm_managed()`](../hooks/hook_civicrm_managed.md)
is recommended.
2. Create an AngularJS module.
3. In the module's `.ang.php` file, set `'basePages' => ['civicrm/search', 'civicrm/admin/search']` and `'exports' => ['name-of-your-search-display']`.
4. Add an admin component (ex: `searchAdminDisplayList.component.js`)
5. Add a display component (ex: `crmSearchDisplayList.component.js`)
## Embedding an afform in a Smarty Page using [Regions](https://docs.civicrm.org/dev/en/latest/framework/region/)
An extension can embed an afform in a CiviCRM Smarty Page using the regions specified in the template. By default, a page would have 3 specified regions: `page-header`, `page-body`, `page-footer`. Additional regions can be added to the page using the `{crmRegion}` tag. The following steps would help in embedding an afform in any of the Smarty Page assigned regions:
1. Identify the region on the page by which the afform would be attached. If the template doesn't have custom regions set, you can either set one or use the default `page-body` region. Using the default `page-body` would attach the afform to the bottom of the page right above the footer.
2. Paste the following code in the [pageRun Hook](https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_pageRun/) of the afform entity's extension:<br/>
```php
if (get_class($page) === '{DISPLAY_PAGE_CLASS_NAME}') {
Civi::service('angularjs.loader')->addModules('{afformModuleName}');
CRM_Core_Region::instance(`{PAGE_REGION}`)->add([
'markup' => '<crm-angular-js modules="{afformModuleName}"><form id="bootstrap-theme"><{afform-directive-name}></afform-directive-name></form></crm-angular-js>',
]);
}
```
- `{DISPLAY_PAGE_CLASS_NAME}` is the class name for the Smarty page. This can be gotten from the Route entity using the url path to the page. For example, to get the class for the page with path `/lorem/ipsum/text` use: `cv api4 Route.get '{"where":[["path","=","lorem/ipsum/text"]],"limit":25,"select":["page_callback"]}'`
- `{afformModuleName}` and `{afform-directive-name}` can be gotten using the Afform entity and the name of the afform (which can be gotten from the formbuilder/search forms list). For example, to get the moduleName and directiveName for an afform named afTestAfform, use: `cv api4 Afform.get '{"where":[["name","=","afTestAfform"]],"limit":25,"select":["module_name","directive_name"]}'`
- `{PAGE_REGION}` is the specific region where you want the afform to be embedded. For pages with no specified region, using `page-body` should place the afform below the last component on the template before the footer.
3. Refreshing the page should display the afform in the position of the page region.
## Passing data to an afform embedded in a Smarty Page to filter a Search table
Here are the steps to pass data into an embedded afform for filtering by an `id`:
1. Add the data to the `options` attribute of the afform. In the example below, the embedded afform (`afSearchTest`) is passed an `id` with value `100` through the options attribute:
```php
if (get_class($page) === 'CRM_Contribute_Page_DashBoard') {
Civi::service('angularjs.loader')->addModules('afSearchTest');
CRM_Core_Region::instance(`{PAGE_REGION}`)->add([
'markup' => '<crm-angular-js modules="afSearchTest"><form id="bootstrap-theme"><afsearch-test options="{id: 100}"></afsearch-test></form></crm-angular-js>',
]);
}
```
2. In the generated afform html file in the `ang` directory, specify this `id` gotten from the `options` attribute as the filter-by value in the search display table:
```html
<crm-search-display-table search-name="MySavedSearch" display-name="MyListDisplay" filters="{id: options.id}"></crm-search-display-table>
```
# Add a Saved Search in Your Own Extension
## Introduction
You can add a saved search created with Search Kit in your own extension.
If you for example created a saved search like the [Soft Credit Example](https://docs.civicrm.org/user/en/latest/searching/searchkit/soft-credit-example/) and want to include it in your extension
to provide an overview of soft credits and related contributions.
You need 2 simple steps to accomplish this
1. Create the saved search and display(s).
2. Export them to a `.mgd.php` file in your extension.
## Automatic Export (civix)
The 2nd step can be most easily done via the [`civix export` command](../extensions/civix.md#export).
## Manual Export
If civix is not available, you can manually export from the overview of Saved Searches or directly in the API4 Explorer.
This guide details the Saved Search overview and will explain how you to do this directly in the API4 Explorer afterwards.
Once you are on the list of saved searches you can click on the action menu behind each row and select the *export* option: ![Saved Searches export](../img/searchkit/exportsearch.png)
If you select this option you will get the option to save the search to the clipboard but also to _package for distribution_: ![Package for distribution](../img/searchkit/apiexport.png) using the API4 Explorer Export.
If you click on the link you will be presented with a prefilled API Explorer for your Saved Search: ![Prefilled API Explorer](../img/searchkit/prefilled.png).
Now press the **Execute** button and copy the results array, then save this results array into the managed folder in your extension (using the **copy** button is a good idea). You'll also need to add `use CRM_Yourextension_ExtensionUtil as E;` to the top of the file (not shown here).
![Result into Managed](../img/searchkit/managed.png)
If you now install your extension in a new environment your defined search will appear in the Saved Search list under the heading Packaged Searches. You'll need to ensure that you have the `mgd-php` in your mixins in `info.xml` for your Saved Search to show up, which you can do by running `civix mixin --enable=mgd-php@1`.